LibreOffice Module sw (master)  1
swcrsr.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 <hintids.hxx>
21 #include <editeng/protitem.hxx>
22 #include <com/sun/star/i18n/WordType.hpp>
23 #include <com/sun/star/i18n/XBreakIterator.hpp>
24 #include <unotools/charclass.hxx>
25 #include <svl/ctloptions.hxx>
26 #include <swmodule.hxx>
27 #include <fmtcntnt.hxx>
28 #include <swtblfmt.hxx>
29 #include <swcrsr.hxx>
30 #include <unocrsr.hxx>
31 #include <bookmrk.hxx>
32 #include <doc.hxx>
33 #include <IDocumentUndoRedo.hxx>
36 #include <docary.hxx>
37 #include <ndtxt.hxx>
38 #include <section.hxx>
39 #include <swtable.hxx>
40 #include <cntfrm.hxx>
41 #include <rootfrm.hxx>
42 #include <txtfrm.hxx>
43 #include <notxtfrm.hxx>
44 #include <scriptinfo.hxx>
45 #include <crstate.hxx>
46 #include <docsh.hxx>
47 #include <viewsh.hxx>
48 #include <frmatr.hxx>
49 #include <breakit.hxx>
50 #include <mdiexp.hxx>
51 #include <strings.hrc>
52 #include <redline.hxx>
53 #include <txatbase.hxx>
54 #include <IDocumentMarkAccess.hxx>
55 #include <memory>
56 #include <comphelper/lok.hxx>
57 #include <editsh.hxx>
58 
59 using namespace ::com::sun::star::i18n;
60 
61 const sal_uInt16 coSrchRplcThreshold = 60000;
62 
63 namespace {
64 
65 struct PercentHdl
66 {
67  SwDocShell* pDSh;
68  sal_uLong nActPos;
69  bool bBack, bNodeIdx;
70 
71  PercentHdl( sal_uLong nStt, sal_uLong nEnd, SwDocShell* pSh )
72  : pDSh(pSh), nActPos(nStt), bBack(false), bNodeIdx(false)
73  {
74  bBack = (nStt > nEnd);
75  if( bBack )
76  {
77  sal_uLong n = nStt; nStt = nEnd; nEnd = n;
78  }
79  ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd );
80  }
81 
82  explicit PercentHdl( const SwPaM& rPam )
83  : pDSh( rPam.GetDoc()->GetDocShell() )
84  {
85  sal_uLong nStt, nEnd;
86  if( rPam.GetPoint()->nNode == rPam.GetMark()->nNode )
87  {
88  bNodeIdx = false;
89  nStt = rPam.GetMark()->nContent.GetIndex();
90  nEnd = rPam.GetPoint()->nContent.GetIndex();
91  }
92  else
93  {
94  bNodeIdx = true;
95  nStt = rPam.GetMark()->nNode.GetIndex();
96  nEnd = rPam.GetPoint()->nNode.GetIndex();
97  }
98  nActPos = nStt;
99  bBack = (nStt > nEnd );
100  if( bBack )
101  {
102  sal_uLong n = nStt; nStt = nEnd; nEnd = n;
103  }
104  ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd, pDSh );
105  }
106 
107  ~PercentHdl() { ::EndProgress( pDSh ); }
108 
109  void NextPos( sal_uLong nPos ) const
110  { ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh ); }
111 
112  void NextPos( SwPosition const & rPos ) const
113  {
114  sal_uLong nPos;
115  if( bNodeIdx )
116  nPos = rPos.nNode.GetIndex();
117  else
118  nPos = rPos.nContent.GetIndex();
119  ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh );
120  }
121 };
122 
123 }
124 
125 SwCursor::SwCursor( const SwPosition &rPos, SwPaM* pRing )
126  : SwPaM( rPos, pRing )
127  , m_nRowSpanOffset(0)
128  , m_nCursorBidiLevel(0)
129  , m_bColumnSelection(false)
130 {
131 }
132 
133 // @@@ semantic: no copy ctor.
134 SwCursor::SwCursor(SwCursor const& rCpy, SwPaM *const pRing)
135  : SwPaM( rCpy, pRing )
136  , m_nRowSpanOffset(rCpy.m_nRowSpanOffset)
137  , m_nCursorBidiLevel(rCpy.m_nCursorBidiLevel)
138  , m_bColumnSelection(rCpy.m_bColumnSelection)
139 {
140 }
141 
143 {
144 }
145 
147 {
148  return new SwCursor( *GetPoint(), pRing );
149 }
150 
152 {
153  return false;
154 }
155 
157 {
158  return true;
159 }
160 
162 {
163  return !IsReadOnlyAvailable();
164 }
165 
166 // CreateNewSavePos is virtual so that derived classes of cursor can implement
167 // own SaveObjects if needed and validate them in the virtual check routines.
169 {
170  m_vSavePos.emplace_back( *this );
171 }
172 
174 {
175  if (!m_vSavePos.empty()) // Robust
176  {
177  m_vSavePos.pop_back();
178  }
179 }
180 
183 {
184  return GetPoint()->nNode.GetIndex() <
186 }
187 
189 {
190  return false;
191 }
192 
193 // extracted from IsSelOvr()
195 {
196  SwNodes& rNds = GetDoc()->GetNodes();
197  // check sections of nodes array
199  && HasMark() )
200  {
201  SwNodeIndex aOldPos( rNds, GetSavePos()->nNode );
202  if( !CheckNodesRange( aOldPos, GetPoint()->nNode, true ))
203  {
204  GetPoint()->nNode = aOldPos;
205  GetPoint()->nContent.Assign( GetContentNode(), GetSavePos()->nContent );
206  return true;
207  }
208  }
209  return SwCursor::IsSelOvrCheck(eFlags);
210 }
211 
212 namespace
213 {
214  const SwTextAttr* InputFieldAtPos(SwPosition const *pPos)
215  {
216  SwTextNode* pTextNd = pPos->nNode.GetNode().GetTextNode();
217  if (!pTextNd)
218  return nullptr;
220  }
221 }
222 
224 {
225  SwDoc* pDoc = GetDoc();
226  SwNodes& rNds = pDoc->GetNodes();
227 
228  bool bSkipOverHiddenSections = IsSkipOverHiddenSections();
229  bool bSkipOverProtectSections = IsSkipOverProtectSections();
230 
231  if ( IsSelOvrCheck( eFlags ) )
232  {
233  return true;
234  }
235 
236  if (m_vSavePos.back().nNode != GetPoint()->nNode.GetIndex() &&
237  // (1997) in UI-ReadOnly everything is allowed
238  ( !pDoc->GetDocShell() || !pDoc->GetDocShell()->IsReadOnlyUI() ))
239  {
240  // check new sections
241  SwNodeIndex& rPtIdx = GetPoint()->nNode;
242  const SwSectionNode* pSectNd = rPtIdx.GetNode().FindSectionNode();
243  if( pSectNd &&
244  ((bSkipOverHiddenSections && pSectNd->GetSection().IsHiddenFlag() ) ||
245  (bSkipOverProtectSections && pSectNd->GetSection().IsProtectFlag() )))
246  {
247  if( !( SwCursorSelOverFlags::ChangePos & eFlags ) )
248  {
249  // then we're already done
250  RestoreSavePos();
251  return true;
252  }
253 
254  // set cursor to new position:
255  SwNodeIndex aIdx( rPtIdx );
256  sal_Int32 nContentPos = m_vSavePos.back().nContent;
257  bool bGoNxt = m_vSavePos.back().nNode < rPtIdx.GetIndex();
258  SwContentNode* pCNd = bGoNxt
259  ? rNds.GoNextSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections)
260  : SwNodes::GoPrevSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections);
261  if( !pCNd && ( SwCursorSelOverFlags::EnableRevDirection & eFlags ))
262  {
263  bGoNxt = !bGoNxt;
264  pCNd = bGoNxt ? rNds.GoNextSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections)
265  : SwNodes::GoPrevSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections);
266  }
267 
268  bool bIsValidPos = nullptr != pCNd;
269  const bool bValidNodesRange = bIsValidPos &&
270  ::CheckNodesRange( rPtIdx, aIdx, true );
271  if( !bValidNodesRange )
272  {
273  rPtIdx = m_vSavePos.back().nNode;
274  pCNd = rPtIdx.GetNode().GetContentNode();
275  if( !pCNd )
276  {
277  bIsValidPos = false;
278  nContentPos = 0;
279  rPtIdx = aIdx;
280  pCNd = rPtIdx.GetNode().GetContentNode();
281  if( !pCNd )
282  {
283  // then to the beginning of the document
284  rPtIdx = rNds.GetEndOfExtras();
285  pCNd = rNds.GoNext( &rPtIdx );
286  }
287  }
288  }
289 
290  // register ContentIndex:
291  const sal_Int32 nTmpPos = bIsValidPos ? (bGoNxt ? 0 : pCNd->Len()) : nContentPos;
292  GetPoint()->nContent.Assign( pCNd, nTmpPos );
293  if( !bIsValidPos || !bValidNodesRange ||
294  IsInProtectTable( true ) )
295  return true;
296  }
297 
298  // is there a protected section in the section?
299  if( HasMark() && bSkipOverProtectSections)
300  {
301  sal_uLong nSttIdx = GetMark()->nNode.GetIndex(),
302  nEndIdx = GetPoint()->nNode.GetIndex();
303  if( nEndIdx <= nSttIdx )
304  {
305  sal_uLong nTmp = nSttIdx;
306  nSttIdx = nEndIdx;
307  nEndIdx = nTmp;
308  }
309 
310  const SwSectionFormats& rFormats = pDoc->GetSections();
311  for( SwSectionFormats::size_type n = 0; n < rFormats.size(); ++n )
312  {
313  const SwSectionFormat* pFormat = rFormats[n];
314  const SvxProtectItem& rProtect = pFormat->GetProtect();
315  if( rProtect.IsContentProtected() )
316  {
317  const SwFormatContent& rContent = pFormat->GetContent(false);
318  OSL_ENSURE( rContent.GetContentIdx(), "No SectionNode?" );
319  sal_uLong nIdx = rContent.GetContentIdx()->GetIndex();
320  if( nSttIdx <= nIdx && nEndIdx >= nIdx )
321  {
322  // if it is no linked section then we cannot select it
323  const SwSection& rSect = *pFormat->GetSection();
324  if( SectionType::Content == rSect.GetType() )
325  {
326  RestoreSavePos();
327  return true;
328  }
329  }
330  }
331  }
332  }
333  }
334 
335  const SwNode* pNd = &GetPoint()->nNode.GetNode();
336  if( pNd->IsContentNode() && !dynamic_cast<SwUnoCursor*>(this) )
337  {
338  const SwContentFrame* pFrame = static_cast<const SwContentNode*>(pNd)->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() );
339  if ( (SwCursorSelOverFlags::ChangePos & eFlags) //allowed to change position if it's a bad one
340  && pFrame && pFrame->isFrameAreaDefinitionValid()
341  && !pFrame->getFrameArea().Height() //a bad zero height position
342  && !InputFieldAtPos(GetPoint()) ) //unless it's a (vertical) input field
343  {
344  // skip to the next/prev valid paragraph with a layout
345  SwNodeIndex& rPtIdx = GetPoint()->nNode;
346  bool bGoNxt = m_vSavePos.back().nNode < rPtIdx.GetIndex();
347  for (;;)
348  {
349  pFrame = bGoNxt ? pFrame->GetNextContentFrame() : pFrame->GetPrevContentFrame();
350  if (!pFrame || 0 != pFrame->getFrameArea().Height() )
351  break;
352  }
353 
354  // #i72394# skip to prev/next valid paragraph with a layout in case
355  // the first search did not succeed:
356  if( !pFrame )
357  {
358  bGoNxt = !bGoNxt;
359  pFrame = static_cast<const SwContentNode*>(pNd)->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() );
360  while ( pFrame && 0 == pFrame->getFrameArea().Height() )
361  {
362  pFrame = bGoNxt ? pFrame->GetNextContentFrame()
363  : pFrame->GetPrevContentFrame();
364  }
365  }
366 
367  if (pFrame != nullptr)
368  {
369  if (pFrame->IsTextFrame())
370  {
371  SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pFrame));
372  *GetPoint() = pTextFrame->MapViewToModelPos(TextFrameIndex(
373  bGoNxt ? 0 : pTextFrame->GetText().getLength()));
374  }
375  else
376  {
377  assert(pFrame->IsNoTextFrame());
378  SwContentNode *const pCNd = const_cast<SwContentNode*>(
379  static_cast<SwNoTextFrame const*>(pFrame)->GetNode());
380  assert(pCNd);
381 
382  // set this ContentNode as new position
383  rPtIdx = *pCNd;
384  // assign corresponding ContentIndex
385  const sal_Int32 nTmpPos = bGoNxt ? 0 : pCNd->Len();
386  GetPoint()->nContent.Assign( pCNd, nTmpPos );
387  }
388 
389 
390  if (rPtIdx.GetIndex() == m_vSavePos.back().nNode
391  && GetPoint()->nContent.GetIndex() == m_vSavePos.back().nContent)
392  {
393  // new position equals saved one
394  // --> trigger restore of saved pos by setting <pFrame> to NULL - see below
395  pFrame = nullptr;
396  }
397 
398  if ( IsInProtectTable( true ) )
399  {
400  // new position in protected table
401  // --> trigger restore of saved pos by setting <pFrame> to NULL - see below
402  pFrame = nullptr;
403  }
404  }
405  }
406 
407  if( !pFrame )
408  {
409  DeleteMark();
410  RestoreSavePos();
411  return true; // we need a frame
412  }
413  }
414 
415  // is the cursor allowed to be in a protected node?
416  if( !( SwCursorSelOverFlags::ChangePos & eFlags ) && !IsAtValidPos() )
417  {
418  DeleteMark();
419  RestoreSavePos();
420  return true;
421  }
422 
423  if( !HasMark() )
424  return false;
425 
426  // check for invalid sections
427  if( !::CheckNodesRange( GetMark()->nNode, GetPoint()->nNode, true ))
428  {
429  DeleteMark();
430  RestoreSavePos();
431  return true; // we need a frame
432  }
433 
434  pNd = &GetMark()->nNode.GetNode();
435  if( pNd->IsContentNode()
436  && !static_cast<const SwContentNode*>(pNd)->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() )
437  && !dynamic_cast<SwUnoCursor*>(this) )
438  {
439  DeleteMark();
440  RestoreSavePos();
441  return true; // we need a frame
442  }
443 
444  // ensure that selection is only inside an InputField or contains the InputField completely
445  {
446  const SwTextAttr* pInputFieldTextAttrAtPoint = InputFieldAtPos(GetPoint());
447  const SwTextAttr* pInputFieldTextAttrAtMark = InputFieldAtPos(GetMark());
448 
449  if ( pInputFieldTextAttrAtPoint != pInputFieldTextAttrAtMark )
450  {
451  const sal_uLong nRefNodeIdx =
452  ( SwCursorSelOverFlags::Toggle & eFlags )
453  ? m_vSavePos.back().nNode
454  : GetMark()->nNode.GetIndex();
455  const sal_Int32 nRefContentIdx =
456  ( SwCursorSelOverFlags::Toggle & eFlags )
457  ? m_vSavePos.back().nContent
458  : GetMark()->nContent.GetIndex();
459  const bool bIsForwardSelection =
460  nRefNodeIdx < GetPoint()->nNode.GetIndex()
461  || ( nRefNodeIdx == GetPoint()->nNode.GetIndex()
462  && nRefContentIdx < GetPoint()->nContent.GetIndex() );
463 
464  if ( pInputFieldTextAttrAtPoint != nullptr )
465  {
466  const sal_Int32 nNewPointPos =
467  bIsForwardSelection ? *(pInputFieldTextAttrAtPoint->End()) : pInputFieldTextAttrAtPoint->GetStart();
468  SwTextNode* pTextNdAtPoint = GetPoint()->nNode.GetNode().GetTextNode();
469  GetPoint()->nContent.Assign( pTextNdAtPoint, nNewPointPos );
470  }
471 
472  if ( pInputFieldTextAttrAtMark != nullptr )
473  {
474  const sal_Int32 nNewMarkPos =
475  bIsForwardSelection ? pInputFieldTextAttrAtMark->GetStart() : *(pInputFieldTextAttrAtMark->End());
476  SwTextNode* pTextNdAtMark = GetMark()->nNode.GetNode().GetTextNode();
477  GetMark()->nContent.Assign( pTextNdAtMark, nNewMarkPos );
478  }
479  }
480  }
481 
482  const SwTableNode* pPtNd = GetPoint()->nNode.GetNode().FindTableNode();
483  const SwTableNode* pMrkNd = GetMark()->nNode.GetNode().FindTableNode();
484  // both in no or in same table node
485  if( ( !pMrkNd && !pPtNd ) || pPtNd == pMrkNd )
486  return false;
487 
488  // in different tables or only mark in table
489  if( pMrkNd )
490  {
491  // not allowed, so go back to old position
492  RestoreSavePos();
493  // Cursor stays at old position
494  return true;
495  }
496 
497  // Note: this cannot happen in TableMode
498  // Only Point in Table then go behind/in front of table
499  if (SwCursorSelOverFlags::ChangePos & eFlags)
500  {
501  bool bSelTop = GetPoint()->nNode.GetIndex() <
502  ((SwCursorSelOverFlags::Toggle & eFlags)
503  ? m_vSavePos.back().nNode : GetMark()->nNode.GetIndex());
504 
505  do { // loop for table after table
506  sal_uLong nSEIdx = pPtNd->EndOfSectionIndex();
507  sal_uLong nSttEndTable = nSEIdx + 1;
508 
509  if( bSelTop )
510  nSttEndTable = rNds[ nSEIdx ]->StartOfSectionIndex() - 1;
511 
512  GetPoint()->nNode = nSttEndTable;
513  const SwNode* pMyNd = &(GetNode());
514 
515  if( pMyNd->IsSectionNode() || ( pMyNd->IsEndNode() &&
516  pMyNd->StartOfSectionNode()->IsSectionNode() ) )
517  {
518  pMyNd = bSelTop
519  ? SwNodes::GoPrevSection( &GetPoint()->nNode,true,false )
520  : rNds.GoNextSection( &GetPoint()->nNode,true,false );
521 
522  /* #i12312# Handle failure of Go{Prev|Next}Section */
523  if ( nullptr == pMyNd)
524  break;
525 
526  pPtNd = pMyNd->FindTableNode();
527  if( pPtNd )
528  continue;
529  }
530 
531  // we permit these
532  if( pMyNd->IsContentNode() &&
533  ::CheckNodesRange( GetMark()->nNode,
534  GetPoint()->nNode, true ))
535  {
536  // table in table
537  const SwTableNode* pOuterTableNd = pMyNd->FindTableNode();
538  if ( pOuterTableNd )
539  pMyNd = pOuterTableNd;
540  else
541  {
542  SwContentNode* pCNd = const_cast<SwContentNode*>(static_cast<const SwContentNode*>(pMyNd));
543  GetPoint()->nContent.Assign( pCNd, bSelTop ? pCNd->Len() : 0 );
544  return false;
545  }
546  }
547  if( bSelTop )
548  {
549  if ( !pMyNd->IsEndNode() )
550  break;
551  pPtNd = pMyNd->FindTableNode();
552  }
553  else
554  pPtNd = pMyNd->GetTableNode();
555  if (!pPtNd)
556  break;
557  } while( true );
558  }
559 
560  // stay on old position
561  RestoreSavePos();
562  return true;
563 }
564 
565 bool SwCursor::IsInProtectTable( bool bMove, bool bChgCursor )
566 {
567  SwContentNode* pCNd = GetContentNode();
568  if( !pCNd )
569  return false;
570 
571  // No table, no protected cell:
572  const SwTableNode* pTableNode = pCNd->FindTableNode();
573  if ( !pTableNode )
574  return false;
575 
576  // Current position == last save position?
577  if (m_vSavePos.back().nNode == GetPoint()->nNode.GetIndex())
578  return false;
579 
580  // Check for covered cell:
581  bool bInCoveredCell = false;
582  const SwStartNode* pTmpSttNode = pCNd->FindTableBoxStartNode();
583  OSL_ENSURE( pTmpSttNode, "In table, therefore I expect to get a SwTableBoxStartNode" );
584  const SwTableBox* pBox = pTmpSttNode ? pTableNode->GetTable().GetTableBox( pTmpSttNode->GetIndex() ) : nullptr; //Robust #151355
585  if ( pBox && pBox->getRowSpan() < 1 ) // Robust #151270
586  bInCoveredCell = true;
587 
588  // Positions of covered cells are not acceptable:
589  if ( !bInCoveredCell )
590  {
591  // Position not protected?
592  if ( !pCNd->IsProtect() )
593  return false;
594 
595  // Cursor in protected cells allowed?
596  if ( IsReadOnlyAvailable() )
597  return false;
598  }
599 
600  // If we reach this point, we are in a protected or covered table cell!
601 
602  if( !bMove )
603  {
604  if( bChgCursor )
605  // restore the last save position
606  RestoreSavePos();
607 
608  return true; // Cursor stays at old position
609  }
610 
611  // We are in a protected table cell. Traverse top to bottom?
612  if (m_vSavePos.back().nNode < GetPoint()->nNode.GetIndex())
613  {
614  // search next valid box
615  // if there is another StartNode after the EndNode of a cell then
616  // there is another cell
617  SwNodeIndex aCellStt( *GetNode().FindTableBoxStartNode()->EndOfSectionNode(), 1 );
618  bool bProt = true;
619 GoNextCell:
620  for (;;) {
621  if( !aCellStt.GetNode().IsStartNode() )
622  break;
623  ++aCellStt;
624  pCNd = aCellStt.GetNode().GetContentNode();
625  if( !pCNd )
626  pCNd = aCellStt.GetNodes().GoNext( &aCellStt );
627  bProt = pCNd->IsProtect();
628  if( !bProt )
629  break;
630  aCellStt.Assign( *pCNd->FindTableBoxStartNode()->EndOfSectionNode(), 1 );
631  }
632 
633 SetNextCursor:
634  if( !bProt ) // found free cell
635  {
636  GetPoint()->nNode = aCellStt;
637  SwContentNode* pTmpCNd = GetContentNode();
638  if( pTmpCNd )
639  {
640  GetPoint()->nContent.Assign( pTmpCNd, 0 );
641  return false;
642  }
645  }
646  // end of table, so go to next node
647  ++aCellStt;
648  SwNode* pNd = &aCellStt.GetNode();
649  if( pNd->IsEndNode() || HasMark())
650  {
651  // if only table in FlyFrame or SSelection then stay on old position
652  if( bChgCursor )
653  RestoreSavePos();
654  return true;
655  }
656  else if( pNd->IsTableNode() && aCellStt++ )
657  goto GoNextCell;
658 
659  bProt = false; // index is now on a content node
660  goto SetNextCursor;
661  }
662 
663  // search for the previous valid box
664  {
665  // if there is another EndNode in front of the StartNode than there
666  // exists a previous cell
667  SwNodeIndex aCellStt( *GetNode().FindTableBoxStartNode(), -1 );
668  SwNode* pNd;
669  bool bProt = true;
670 GoPrevCell:
671  for (;;) {
672  pNd = &aCellStt.GetNode();
673  if( !pNd->IsEndNode() )
674  break;
675  aCellStt.Assign( *pNd->StartOfSectionNode(), +1 );
676  pCNd = aCellStt.GetNode().GetContentNode();
677  if( !pCNd )
678  pCNd = pNd->GetNodes().GoNext( &aCellStt );
679  bProt = pCNd->IsProtect();
680  if( !bProt )
681  break;
682  aCellStt.Assign( *pNd->FindTableBoxStartNode(), -1 );
683  }
684 
685 SetPrevCursor:
686  if( !bProt ) // found free cell
687  {
688  GetPoint()->nNode = aCellStt;
689  SwContentNode* pTmpCNd = GetContentNode();
690  if( pTmpCNd )
691  {
692  GetPoint()->nContent.Assign( pTmpCNd, 0 );
693  return false;
694  }
697  }
698  // at the beginning of a table, so go to next node
699  --aCellStt;
700  pNd = &aCellStt.GetNode();
701  if( pNd->IsStartNode() || HasMark() )
702  {
703  // if only table in FlyFrame or SSelection then stay on old position
704  if( bChgCursor )
705  RestoreSavePos();
706  return true;
707  }
708  else if( pNd->StartOfSectionNode()->IsTableNode() && aCellStt-- )
709  goto GoPrevCell;
710 
711  bProt = false; // index is now on a content node
712  goto SetPrevCursor;
713  }
714 }
715 
717 bool SwCursor::IsAtValidPos( bool bPoint ) const
718 {
719  const SwDoc* pDoc = GetDoc();
720  const SwPosition* pPos = bPoint ? GetPoint() : GetMark();
721  const SwNode* pNd = &pPos->nNode.GetNode();
722 
723  if( pNd->IsContentNode() && !static_cast<const SwContentNode*>(pNd)->getLayoutFrame( pDoc->getIDocumentLayoutAccess().GetCurrentLayout() ) &&
724  !dynamic_cast<const SwUnoCursor*>(this) )
725  {
726  return false;
727  }
728 
729  // #i45129# - in UI-ReadOnly everything is allowed
730  if( !pDoc->GetDocShell() || !pDoc->GetDocShell()->IsReadOnlyUI() )
731  return true;
732 
733  const bool bCursorInReadOnly = IsReadOnlyAvailable();
734  if( !bCursorInReadOnly && pNd->IsProtect() )
735  return false;
736 
737  const SwSectionNode* pSectNd = pNd->FindSectionNode();
738  return !pSectNd
739  || !(pSectNd->GetSection().IsHiddenFlag() ||
740  ( !bCursorInReadOnly && pSectNd->GetSection().IsProtectFlag() ));
741 }
742 
744 
747  SwDocPositions nEnd, SwPaM* pRange ) const
748 {
749  pRange->SetMark();
750  FillFindPos( nStart, *pRange->GetMark() );
751  FillFindPos( nEnd, *pRange->GetPoint() );
752 
753  // determine direction of search
754  return ( SwDocPositions::Start == nStart || SwDocPositions::OtherStart == nStart ||
755  (SwDocPositions::Curr == nStart &&
756  (SwDocPositions::End == nEnd || SwDocPositions::OtherEnd == nEnd ) ))
758 }
759 
760 static sal_uLong lcl_FindSelection( SwFindParas& rParas, SwCursor* pCurrentCursor,
761  SwMoveFnCollection const & fnMove, SwCursor*& pFndRing,
762  SwPaM& aRegion, FindRanges eFndRngs,
763  bool bInReadOnly, bool& bCancel )
764 {
765  SwDoc* pDoc = pCurrentCursor->GetDoc();
766  bool const bDoesUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
767  int nFndRet = 0;
768  sal_uLong nFound = 0;
769  const bool bSrchBkwrd = &fnMove == &fnMoveBackward;
770  SwPaM *pTmpCursor = pCurrentCursor, *pSaveCursor = pCurrentCursor;
771 
772  // only create progress bar for ShellCursor
773  bool bIsUnoCursor = dynamic_cast<SwUnoCursor*>(pCurrentCursor) != nullptr;
774  std::unique_ptr<PercentHdl> pPHdl;
775  sal_uInt16 nCursorCnt = 0;
776  if( FindRanges::InSel & eFndRngs )
777  {
778  while( pCurrentCursor != ( pTmpCursor = pTmpCursor->GetNext() ))
779  ++nCursorCnt;
780  if( nCursorCnt && !bIsUnoCursor )
781  pPHdl.reset(new PercentHdl( 0, nCursorCnt, pDoc->GetDocShell() ));
782  }
783  else
784  pSaveCursor = pSaveCursor->GetPrev();
785 
786  bool bEnd = false;
787  do {
788  aRegion.SetMark();
789  // independent from search direction: SPoint is always bigger than mark
790  // if the search area is valid
791  SwPosition *pSttPos = aRegion.GetMark(),
792  *pEndPos = aRegion.GetPoint();
793  *pSttPos = *pTmpCursor->Start();
794  *pEndPos = *pTmpCursor->End();
795  if( bSrchBkwrd )
796  aRegion.Exchange();
797 
798  if( !nCursorCnt && !pPHdl && !bIsUnoCursor )
799  pPHdl.reset(new PercentHdl( aRegion ));
800 
801  // as long as found and not at same position
802  while( *pSttPos <= *pEndPos )
803  {
804  nFndRet = rParas.DoFind(*pCurrentCursor, fnMove, aRegion, bInReadOnly);
805  if( 0 == nFndRet ||
806  ( pFndRing &&
807  *pFndRing->GetPoint() == *pCurrentCursor->GetPoint() &&
808  *pFndRing->GetMark() == *pCurrentCursor->GetMark() ))
809  break;
810  if( !( FIND_NO_RING & nFndRet ))
811  {
812  // #i24084# - create ring similar to the one in CreateCursor
813  SwCursor* pNew = pCurrentCursor->Create( pFndRing );
814  if( !pFndRing )
815  pFndRing = pNew;
816 
817  pNew->SetMark();
818  *pNew->GetMark() = *pCurrentCursor->GetMark();
819  }
820 
821  ++nFound;
822 
823  if( !( eFndRngs & FindRanges::InSelAll) )
824  {
825  bEnd = true;
826  break;
827  }
828 
829  if ((coSrchRplcThreshold == nFound)
830  && pDoc->GetIDocumentUndoRedo().DoesUndo()
831  && rParas.IsReplaceMode())
832  {
833  short nRet = pCurrentCursor->MaxReplaceArived();
834  if( RET_YES == nRet )
835  {
837  pDoc->GetIDocumentUndoRedo().DoUndo(false);
838  }
839  else
840  {
841  bEnd = true;
842  if(RET_CANCEL == nRet)
843  {
844  bCancel = true;
845  }
846  break;
847  }
848  }
849 
850  if( bSrchBkwrd )
851  // move pEndPos in front of the found area
852  *pEndPos = *pCurrentCursor->Start();
853  else
854  // move pSttPos behind the found area
855  *pSttPos = *pCurrentCursor->End();
856 
857  if( *pSttPos == *pEndPos )
858  // in area but at the end => done
859  break;
860 
861  if( !nCursorCnt && pPHdl )
862  {
863  pPHdl->NextPos( *aRegion.GetMark() );
864  }
865  }
866 
867  if( bEnd || !( eFndRngs & ( FindRanges::InSelAll | FindRanges::InSel )) )
868  break;
869 
870  pTmpCursor = pTmpCursor->GetNext();
871  if( nCursorCnt && pPHdl )
872  {
873  pPHdl->NextPos( ++pPHdl->nActPos );
874  }
875 
876  } while( pTmpCursor != pSaveCursor && pTmpCursor->GetNext() != pTmpCursor);
877 
878  if( nFound && !pFndRing ) // if no ring should be created
879  pFndRing = pCurrentCursor->Create();
880 
881  pDoc->GetIDocumentUndoRedo().DoUndo(bDoesUndo);
882  return nFound;
883 }
884 
885 static bool lcl_MakeSelFwrd( const SwNode& rSttNd, const SwNode& rEndNd,
886  SwPaM& rPam, bool bFirst )
887 {
888  if( rSttNd.GetIndex() + 1 == rEndNd.GetIndex() )
889  return false;
890 
891  SwNodes& rNds = rPam.GetDoc()->GetNodes();
892  rPam.DeleteMark();
893  SwContentNode* pCNd;
894  if( !bFirst )
895  {
896  rPam.GetPoint()->nNode = rSttNd;
897  pCNd = rNds.GoNext( &rPam.GetPoint()->nNode );
898  if( !pCNd )
899  return false;
900  pCNd->MakeStartIndex( &rPam.GetPoint()->nContent );
901  }
902  else if( rSttNd.GetIndex() > rPam.GetPoint()->nNode.GetIndex() ||
903  rPam.GetPoint()->nNode.GetIndex() >= rEndNd.GetIndex() )
904  // not in this section
905  return false;
906 
907  rPam.SetMark();
908  rPam.GetPoint()->nNode = rEndNd;
909  pCNd = SwNodes::GoPrevious( &rPam.GetPoint()->nNode );
910  if( !pCNd )
911  return false;
912  pCNd->MakeEndIndex( &rPam.GetPoint()->nContent );
913 
914  return *rPam.GetMark() < *rPam.GetPoint();
915 }
916 
917 static bool lcl_MakeSelBkwrd( const SwNode& rSttNd, const SwNode& rEndNd,
918  SwPaM& rPam, bool bFirst )
919 {
920  if( rEndNd.GetIndex() + 1 == rSttNd.GetIndex() )
921  return false;
922 
923  SwNodes& rNds = rPam.GetDoc()->GetNodes();
924  rPam.DeleteMark();
925  SwContentNode* pCNd;
926  if( !bFirst )
927  {
928  rPam.GetPoint()->nNode = rSttNd;
929  pCNd = SwNodes::GoPrevious( &rPam.GetPoint()->nNode );
930  if( !pCNd )
931  return false;
932  pCNd->MakeEndIndex( &rPam.GetPoint()->nContent );
933  }
934  else if( rEndNd.GetIndex() > rPam.GetPoint()->nNode.GetIndex() ||
935  rPam.GetPoint()->nNode.GetIndex() >= rSttNd.GetIndex() )
936  return false; // not in this section
937 
938  rPam.SetMark();
939  rPam.GetPoint()->nNode = rEndNd;
940  pCNd = rNds.GoNext( &rPam.GetPoint()->nNode );
941  if( !pCNd )
942  return false;
943  pCNd->MakeStartIndex( &rPam.GetPoint()->nContent );
944 
945  return *rPam.GetPoint() < *rPam.GetMark();
946 }
947 
948 // this method "searches" for all use cases because in SwFindParas is always the
949 // correct parameters and respective search method
951  SwDocPositions nStart, SwDocPositions nEnd,
952  FindRanges eFndRngs, bool& bCancel )
953 {
954  bCancel = false;
955  SwCursorSaveState aSaveState( *this );
956 
957  // create region without adding it to the ring
958  SwPaM aRegion( *GetPoint() );
959  SwMoveFnCollection const & fnMove = MakeFindRange( nStart, nEnd, &aRegion );
960 
961  sal_uLong nFound = 0;
962  const bool bMvBkwrd = &fnMove == &fnMoveBackward;
963  bool bInReadOnly = IsReadOnlyAvailable();
964 
965  SwCursor* pFndRing = nullptr;
966  SwNodes& rNds = GetDoc()->GetNodes();
967 
968  // search in sections?
969  if( FindRanges::InSel & eFndRngs )
970  {
971  // if string was not found in region then get all sections (cursors
972  // stays unchanged)
973  nFound = lcl_FindSelection( rParas, this, fnMove,
974  pFndRing, aRegion, eFndRngs,
975  bInReadOnly, bCancel );
976  if( 0 == nFound )
977  return nFound;
978 
979  // found string at least once; it's all in new Cursor ring thus delete old one
980  while( GetNext() != this )
981  delete GetNext();
982 
983  *GetPoint() = *pFndRing->GetPoint();
984  SetMark();
985  *GetMark() = *pFndRing->GetMark();
986  pFndRing->GetRingContainer().merge( GetRingContainer() );
987  delete pFndRing;
988  }
989  else if( FindRanges::InOther & eFndRngs )
990  {
991  // put cursor as copy of current into ring
992  // chaining points always to first created, so forward
993  SwCursor* pSav = Create( this ); // save the current cursor
994 
995  // if already outside of body text search from this position or start at
996  // 1. base section
997  if( bMvBkwrd
1000  *this, rNds.GetEndOfExtras().GetIndex() >=
1001  GetPoint()->nNode.GetIndex() )
1003  rNds.GetEndOfExtras(), *this,
1004  rNds.GetEndOfExtras().GetIndex() >=
1005  GetPoint()->nNode.GetIndex() ))
1006  {
1007  nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing,
1008  aRegion, eFndRngs, bInReadOnly, bCancel );
1009  }
1010 
1011  if( !nFound )
1012  {
1013  // put back the old one
1014  *GetPoint() = *pSav->GetPoint();
1015  if( pSav->HasMark() )
1016  {
1017  SetMark();
1018  *GetMark() = *pSav->GetMark();
1019  }
1020  else
1021  DeleteMark();
1022  return 0;
1023  }
1024 
1025  if( !( FindRanges::InSelAll & eFndRngs ))
1026  {
1027  // there should only be a single one, thus add it
1028  // independent from search direction: SPoint is always bigger than
1029  // mark if the search area is valid
1030  *GetPoint() = *pFndRing->GetPoint();
1031  SetMark();
1032  *GetMark() = *pFndRing->GetMark();
1033  }
1034  else
1035  {
1036  // found string at least once; it's all in new Cursor ring thus delete old one
1037  while( GetNext() != this )
1038  delete GetNext();
1039 
1040  *GetPoint() = *pFndRing->GetPoint();
1041  SetMark();
1042  *GetMark() = *pFndRing->GetMark();
1043  pFndRing->GetRingContainer().merge( GetRingContainer() );
1044  }
1045  delete pFndRing;
1046  }
1047  else if( FindRanges::InSelAll & eFndRngs )
1048  {
1049  SwCursor* pSav = Create( this ); // save the current cursor
1050 
1051  const SwNode* pSttNd = ( FindRanges::InBodyOnly & eFndRngs )
1054 
1055  if( bMvBkwrd
1056  ? lcl_MakeSelBkwrd( rNds.GetEndOfContent(), *pSttNd, *this, false )
1057  : lcl_MakeSelFwrd( *pSttNd, rNds.GetEndOfContent(), *this, false ))
1058  {
1059  nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing,
1060  aRegion, eFndRngs, bInReadOnly, bCancel );
1061  }
1062 
1063  if( !nFound )
1064  {
1065  // put back the old one
1066  *GetPoint() = *pSav->GetPoint();
1067  if( pSav->HasMark() )
1068  {
1069  SetMark();
1070  *GetMark() = *pSav->GetMark();
1071  }
1072  else
1073  DeleteMark();
1074  return 0;
1075  }
1076  while( GetNext() != this )
1077  delete GetNext();
1078 
1079  *GetPoint() = *pFndRing->GetPoint();
1080  SetMark();
1081  *GetMark() = *pFndRing->GetMark();
1082  pFndRing->GetRingContainer().merge( GetRingContainer() );
1083  delete pFndRing;
1084  }
1085  else
1086  {
1087  // if a GetMark is set then keep the GetMark of the found object
1088  // This allows spanning an area with this search.
1089  SwPosition aMarkPos( *GetMark() );
1090  const bool bMarkPos = HasMark() && (eFndRngs == FindRanges::InBody);
1091 
1092  nFound = rParas.DoFind(*this, fnMove, aRegion, bInReadOnly) ? 1 : 0;
1093  if (0 != nFound && bMarkPos)
1094  *GetMark() = aMarkPos;
1095  }
1096 
1098  nFound = 0;
1099  return nFound;
1100 }
1101 
1103 {
1104  bool bIsStart = true;
1105  SwContentNode* pCNd = nullptr;
1106  SwNodes& rNds = GetDoc()->GetNodes();
1107 
1108  switch( ePos )
1109  {
1110  case SwDocPositions::Start:
1111  rPos.nNode = *rNds.GetEndOfContent().StartOfSectionNode();
1112  pCNd = rNds.GoNext( &rPos.nNode );
1113  break;
1114  case SwDocPositions::End:
1115  rPos.nNode = rNds.GetEndOfContent();
1116  pCNd = SwNodes::GoPrevious( &rPos.nNode );
1117  bIsStart = false;
1118  break;
1120  rPos.nNode = *rNds[ sal_uLong(0) ];
1121  pCNd = rNds.GoNext( &rPos.nNode );
1122  break;
1124  rPos.nNode = *rNds.GetEndOfContent().StartOfSectionNode();
1125  pCNd = SwNodes::GoPrevious( &rPos.nNode );
1126  bIsStart = false;
1127  break;
1128  default:
1129  rPos = *GetPoint();
1130  }
1131 
1132  if( pCNd )
1133  {
1134  rPos.nContent.Assign( pCNd, bIsStart ? 0 : pCNd->Len() );
1135  }
1136 }
1137 
1139 {
1140  return RET_YES;
1141 }
1142 
1143 namespace {
1144 
1145 struct HideWrapper
1146 {
1147  // either the frame's text or the node's text (possibly pre-filtered)
1148  OUString const* m_pText;
1149  // this is actually a TextFrameIndex but all of the i18n code uses sal_Int32
1150  sal_Int32 m_nPtIndex;
1151  // if mapping is needed, use this frame
1152  SwTextFrame * m_pFrame;
1153  // input in the constructor, output (via mapping) in the destructor
1154  SwTextNode *& m_rpTextNode;
1155  sal_Int32 & m_rPtPos;
1156 
1157  HideWrapper(SwRootFrame const*const pLayout,
1158  SwTextNode *& rpTextNode, sal_Int32 & rPtPos,
1159  OUString const*const pFilteredNodeText = nullptr)
1160  : m_pText(pFilteredNodeText)
1161  , m_pFrame(nullptr)
1162  , m_rpTextNode(rpTextNode)
1163  , m_rPtPos(rPtPos)
1164  {
1165  if (pLayout && pLayout->IsHideRedlines())
1166  {
1167  m_pFrame = static_cast<SwTextFrame*>(rpTextNode->getLayoutFrame(pLayout));
1168  m_pText = &m_pFrame->GetText();
1169  m_nPtIndex = sal_Int32(m_pFrame->MapModelToView(rpTextNode, rPtPos));
1170  }
1171  else
1172  {
1173  if (!m_pText)
1174  {
1175  m_pText = &rpTextNode->GetText();
1176  }
1177  m_nPtIndex = rPtPos;
1178  }
1179  }
1180  ~HideWrapper()
1181  {
1182  AssignBack(m_rpTextNode, m_rPtPos);
1183  }
1184  void AssignBack(SwTextNode *& rpTextNode, sal_Int32 & rPtPos)
1185  {
1186  if (0 <= m_nPtIndex && m_pFrame)
1187  {
1188  std::pair<SwTextNode*, sal_Int32> const pos(
1189  m_pFrame->MapViewToModel(TextFrameIndex(m_nPtIndex)));
1190  rpTextNode = pos.first;
1191  rPtPos = pos.second;
1192  }
1193  else
1194  {
1195  rPtPos = m_nPtIndex;
1196  }
1197  }
1198 };
1199 
1200 } // namespace
1201 
1202 bool SwCursor::SelectWord( SwViewShell const * pViewShell, const Point* pPt )
1203 {
1204  return SelectWordWT( pViewShell, WordType::ANYWORD_IGNOREWHITESPACES, pPt );
1205 }
1206 
1207 bool SwCursor::IsStartWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout) const
1208 {
1209  bool bRet = false;
1210  SwTextNode* pTextNd = GetNode().GetTextNode();
1211  if (pTextNd)
1212  {
1213  sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
1214 
1215  HideWrapper w(pLayout, pTextNd, nPtPos);
1216 
1217  bRet = g_pBreakIt->GetBreakIter()->isBeginWord(
1218  *w.m_pText, w.m_nPtIndex,
1219  g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos )),
1220  nWordType );
1221  }
1222  return bRet;
1223 }
1224 
1225 bool SwCursor::IsEndWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout) const
1226 {
1227  bool bRet = false;
1228  SwTextNode* pTextNd = GetNode().GetTextNode();
1229  if (pTextNd)
1230  {
1231  sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
1232 
1233  HideWrapper w(pLayout, pTextNd, nPtPos);
1234 
1235  bRet = g_pBreakIt->GetBreakIter()->isEndWord(
1236  *w.m_pText, w.m_nPtIndex,
1237  g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1238  nWordType );
1239 
1240  }
1241  return bRet;
1242 }
1243 
1244 bool SwCursor::IsInWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout) const
1245 {
1246  bool bRet = false;
1247  SwTextNode* pTextNd = GetNode().GetTextNode();
1248  if (pTextNd)
1249  {
1250  sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
1251 
1252  {
1253  HideWrapper w(pLayout, pTextNd, nPtPos);
1254 
1255  Boundary aBoundary = g_pBreakIt->GetBreakIter()->getWordBoundary(
1256  *w.m_pText, w.m_nPtIndex,
1257  g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1258  nWordType,
1259  true );
1260 
1261  bRet = aBoundary.startPos != aBoundary.endPos &&
1262  aBoundary.startPos <= w.m_nPtIndex &&
1263  w.m_nPtIndex <= aBoundary.endPos;
1264  w.m_nPtIndex = aBoundary.startPos; // hack: convert startPos back...
1265  }
1266  if(bRet)
1267  {
1268  const CharClass& rCC = GetAppCharClass();
1269  bRet = rCC.isLetterNumeric(pTextNd->GetText(), nPtPos);
1270  }
1271  }
1272  return bRet;
1273 }
1274 
1275 bool SwCursor::IsStartEndSentence(bool bEnd, SwRootFrame const*const pLayout) const
1276 {
1277  bool bRet = bEnd ?
1279  GetPoint()->nContent.GetIndex() == 0;
1280 
1281  if ((pLayout != nullptr && pLayout->IsHideRedlines()) || !bRet)
1282  {
1283  SwCursor aCursor(*GetPoint(), nullptr);
1284  SwPosition aOrigPos = *aCursor.GetPoint();
1285  aCursor.GoSentence(bEnd ? SwCursor::END_SENT : SwCursor::START_SENT, pLayout);
1286  bRet = aOrigPos == *aCursor.GetPoint();
1287  }
1288  return bRet;
1289 }
1290 
1291 bool SwCursor::GoStartWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
1292 {
1293  bool bRet = false;
1294  SwTextNode* pTextNd = GetNode().GetTextNode();
1295  if (pTextNd)
1296  {
1297  SwCursorSaveState aSave( *this );
1298  sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
1299 
1300  {
1301  HideWrapper w(pLayout, pTextNd, nPtPos);
1302 
1303  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->getWordBoundary(
1304  *w.m_pText, w.m_nPtIndex,
1305  g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1306  nWordType,
1307  false ).startPos;
1308  }
1309 
1310  if (nPtPos < pTextNd->GetText().getLength() && nPtPos >= 0)
1311  {
1312  *GetPoint() = SwPosition(*pTextNd, nPtPos);
1313  if( !IsSelOvr() )
1314  bRet = true;
1315  }
1316  }
1317  return bRet;
1318 }
1319 
1320 bool SwCursor::GoEndWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
1321 {
1322  bool bRet = false;
1323  SwTextNode* pTextNd = GetNode().GetTextNode();
1324  if (pTextNd)
1325  {
1326  SwCursorSaveState aSave( *this );
1327  sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
1328 
1329  {
1330  HideWrapper w(pLayout, pTextNd, nPtPos);
1331 
1332  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->getWordBoundary(
1333  *w.m_pText, w.m_nPtIndex,
1334  g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1335  nWordType,
1336  true ).endPos;
1337  }
1338 
1339  if (nPtPos <= pTextNd->GetText().getLength() && nPtPos >= 0 &&
1340  GetPoint()->nContent.GetIndex() != nPtPos )
1341  {
1342  *GetPoint() = SwPosition(*pTextNd, nPtPos);
1343  if( !IsSelOvr() )
1344  bRet = true;
1345  }
1346  }
1347  return bRet;
1348 }
1349 
1350 bool SwCursor::GoNextWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
1351 {
1352  bool bRet = false;
1353  SwTextNode* pTextNd = GetNode().GetTextNode();
1354  if (pTextNd)
1355  {
1356  SwCursorSaveState aSave( *this );
1357  sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
1358 
1359  {
1360  HideWrapper w(pLayout, pTextNd, nPtPos);
1361 
1362  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->nextWord(
1363  *w.m_pText, w.m_nPtIndex,
1364  g_pBreakIt->GetLocale( pTextNd->GetLang(nPtPos, 1) ),
1365  nWordType ).startPos;
1366  }
1367 
1368  if (nPtPos <= pTextNd->GetText().getLength() && nPtPos >= 0)
1369  {
1370  *GetPoint() = SwPosition(*pTextNd, nPtPos);
1371  if( !IsSelOvr() )
1372  bRet = true;
1373  }
1374  }
1375  return bRet;
1376 }
1377 
1378 bool SwCursor::GoPrevWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
1379 {
1380  bool bRet = false;
1381  SwTextNode* pTextNd = GetNode().GetTextNode();
1382  if (pTextNd)
1383  {
1384  SwCursorSaveState aSave( *this );
1385  sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
1386 
1387  {
1388  HideWrapper w(pLayout, pTextNd, nPtPos);
1389 
1390  const sal_Int32 nPtStart = w.m_nPtIndex;
1391  if (w.m_nPtIndex)
1392  {
1393  --w.m_nPtIndex;
1394  w.AssignBack(pTextNd, nPtPos);
1395  }
1396 
1397  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->previousWord(
1398  *w.m_pText, nPtStart,
1399  g_pBreakIt->GetLocale( pTextNd->GetLang(nPtPos, 1) ),
1400  nWordType ).startPos;
1401  }
1402 
1403  if (nPtPos < pTextNd->GetText().getLength() && nPtPos >= 0)
1404  {
1405  *GetPoint() = SwPosition(*pTextNd, nPtPos);
1406  if( !IsSelOvr() )
1407  bRet = true;
1408  }
1409  }
1410  return bRet;
1411 }
1412 
1413 bool SwCursor::SelectWordWT( SwViewShell const * pViewShell, sal_Int16 nWordType, const Point* pPt )
1414 {
1415  SwCursorSaveState aSave( *this );
1416 
1417  bool bRet = false;
1418  DeleteMark();
1419  const SwRootFrame* pLayout = pViewShell->GetLayout();
1420  if( pPt && nullptr != pLayout )
1421  {
1422  // set the cursor to the layout position
1423  Point aPt( *pPt );
1424  pLayout->GetModelPositionForViewPoint( GetPoint(), aPt );
1425  }
1426 
1427  SwTextNode* pTextNd = GetNode().GetTextNode();
1428  if (pTextNd)
1429  {
1430  // Should we select the whole fieldmark?
1431  const IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess( );
1432  sw::mark::IFieldmark const*const pMark(pMarksAccess->getFieldmarkFor(*GetPoint()));
1435  {
1436  *GetPoint() = sw::mark::FindFieldSep(*pMark);
1437  ++GetPoint()->nContent; // Don't select the separator
1438 
1439  const SwPosition& rEnd = pMark->GetMarkEnd();
1440 
1441  assert(pMark->GetMarkEnd() != *GetPoint());
1442  SetMark();
1443  GetMark()->nNode = rEnd.nNode;
1444  GetMark()->nContent = rEnd.nContent;
1445  --GetMark()->nContent; // Don't select the end delimiter
1446 
1447  bRet = true;
1448  }
1449  else
1450  {
1451  bool bForward = true;
1452  sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
1453 
1454  HideWrapper w(pViewShell->GetLayout(), pTextNd, nPtPos);
1455 
1456  Boundary aBndry( g_pBreakIt->GetBreakIter()->getWordBoundary(
1457  *w.m_pText, w.m_nPtIndex,
1458  g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1459  nWordType,
1460  bForward ));
1461 
1462  if (comphelper::LibreOfficeKit::isActive() && aBndry.startPos == aBndry.endPos && w.m_nPtIndex > 0)
1463  {
1464  // nPtPos is the end of the paragraph, select the last word then.
1465  --w.m_nPtIndex;
1466  w.AssignBack(pTextNd, nPtPos);
1467 
1468  aBndry = g_pBreakIt->GetBreakIter()->getWordBoundary(
1469  *w.m_pText, w.m_nPtIndex,
1470  g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
1471  nWordType,
1472  bForward );
1473 
1474  }
1475 
1476  SwTextNode * pStartNode(pTextNd);
1477  sal_Int32 nStartIndex;
1478  w.m_nPtIndex = aBndry.startPos;
1479  w.AssignBack(pStartNode, nStartIndex);
1480 
1481  SwTextNode * pEndNode(pTextNd);
1482  sal_Int32 nEndIndex;
1483  w.m_nPtIndex = aBndry.endPos;
1484  w.AssignBack(pEndNode, nEndIndex);
1485 
1486  if( aBndry.startPos != aBndry.endPos )
1487  {
1488  *GetPoint() = SwPosition(*pEndNode, nEndIndex);
1489  if( !IsSelOvr() )
1490  {
1491  SetMark();
1492  *GetMark() = SwPosition(*pStartNode, nStartIndex);
1493  if (sw::mark::IMark* pAnnotationMark = pMarksAccess->getAnnotationMarkFor(*GetPoint()))
1494  {
1495  // An annotation mark covers the selected word. Check
1496  // if it covers only the word: in that case we select
1497  // the comment anchor as well.
1498  bool bStartMatch = GetMark()->nNode == pAnnotationMark->GetMarkStart().nNode &&
1499  GetMark()->nContent == pAnnotationMark->GetMarkStart().nContent;
1500  bool bEndMatch = GetPoint()->nNode == pAnnotationMark->GetMarkEnd().nNode &&
1501  GetPoint()->nContent.GetIndex() + 1 == pAnnotationMark->GetMarkEnd().nContent.GetIndex();
1502  if (bStartMatch && bEndMatch)
1503  ++GetPoint()->nContent;
1504  }
1505  if( !IsSelOvr() )
1506  bRet = true;
1507  }
1508  }
1509  }
1510  }
1511 
1512  if( !bRet )
1513  {
1514  DeleteMark();
1515  RestoreSavePos();
1516  }
1517  return bRet;
1518 }
1519 
1520 static OUString lcl_MaskDeletedRedlines( const SwTextNode* pTextNd )
1521 {
1522  OUString aRes;
1523  if (pTextNd)
1524  {
1525  //mask deleted redlines
1526  OUString sNodeText(pTextNd->GetText());
1527  const SwDoc& rDoc = *pTextNd->GetDoc();
1528  const bool bShowChg = IDocumentRedlineAccess::IsShowChanges( rDoc.getIDocumentRedlineAccess().GetRedlineFlags() );
1529  if ( bShowChg )
1530  {
1531  SwRedlineTable::size_type nAct = rDoc.getIDocumentRedlineAccess().GetRedlinePos( *pTextNd, RedlineType::Any );
1532  for ( ; nAct < rDoc.getIDocumentRedlineAccess().GetRedlineTable().size(); nAct++ )
1533  {
1534  const SwRangeRedline* pRed = rDoc.getIDocumentRedlineAccess().GetRedlineTable()[ nAct ];
1535  if ( pRed->Start()->nNode > pTextNd->GetIndex() )
1536  break;
1537 
1538  if( RedlineType::Delete == pRed->GetType() )
1539  {
1540  sal_Int32 nStart, nEnd;
1541  pRed->CalcStartEnd( pTextNd->GetIndex(), nStart, nEnd );
1542 
1543  while ( nStart < nEnd && nStart < sNodeText.getLength() )
1544  sNodeText = sNodeText.replaceAt( nStart++, 1, OUString(CH_TXTATR_INWORD) );
1545  }
1546  }
1547  }
1548  aRes = sNodeText;
1549  }
1550  return aRes;
1551 }
1552 
1553 bool SwCursor::GoSentence(SentenceMoveType eMoveType, SwRootFrame const*const pLayout)
1554 {
1555  bool bRet = false;
1556  SwTextNode* pTextNd = GetNode().GetTextNode();
1557  if (pTextNd)
1558  {
1559  OUString const sNodeText(lcl_MaskDeletedRedlines(pTextNd));
1560 
1561  SwCursorSaveState aSave( *this );
1562  sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
1563 
1564  {
1565  HideWrapper w(pLayout, pTextNd, nPtPos, &sNodeText);
1566 
1567  switch ( eMoveType )
1568  {
1569  case START_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
1570  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
1571  *w.m_pText, w.m_nPtIndex,
1572  g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1573  break;
1574  case END_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
1575  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->endOfSentence(
1576  *w.m_pText, w.m_nPtIndex,
1577  g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1578  break;
1579  case NEXT_SENT:
1580  {
1581  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->endOfSentence(
1582  *w.m_pText, w.m_nPtIndex,
1583  g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1584  if (w.m_nPtIndex >= 0 && w.m_nPtIndex < w.m_pText->getLength())
1585  {
1586  do
1587  {
1588  ++w.m_nPtIndex;
1589  }
1590  while (w.m_nPtIndex < w.m_pText->getLength()
1591  && (*w.m_pText)[w.m_nPtIndex] == ' ');
1592  }
1593  break;
1594  }
1595  case PREV_SENT:
1596  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
1597  *w.m_pText, w.m_nPtIndex,
1598  g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1599 
1600  if (w.m_nPtIndex == 0)
1601  return false; // the previous sentence is not in this paragraph
1602  if (w.m_nPtIndex > 0)
1603  {
1604  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
1605  *w.m_pText, w.m_nPtIndex - 1,
1606  g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
1607  }
1608  break;
1609  }
1610  }
1611 
1612  // it is allowed to place the PaM just behind the last
1613  // character in the text thus <= ...Len
1614  if (nPtPos <= pTextNd->GetText().getLength() && nPtPos >= 0)
1615  {
1616  *GetPoint() = SwPosition(*pTextNd, nPtPos);
1617  if( !IsSelOvr() )
1618  bRet = true;
1619  }
1620  }
1621  return bRet;
1622 }
1623 
1625 {
1626  bool bRes = false;
1627  SwTextNode* pStartNd = Start()->nNode.GetNode().GetTextNode();
1628  SwTextNode* pEndNd = End()->nNode.GetNode().GetTextNode();
1629  if (pStartNd && pEndNd)
1630  {
1631  if (!HasMark())
1632  SetMark();
1633 
1634  OUString sStartText( lcl_MaskDeletedRedlines( pStartNd ) );
1635  OUString sEndText( pStartNd == pEndNd? sStartText : lcl_MaskDeletedRedlines( pEndNd ) );
1636 
1637  SwCursorSaveState aSave( *this );
1638  sal_Int32 nStartPos = Start()->nContent.GetIndex();
1639  sal_Int32 nEndPos = End()->nContent.GetIndex();
1640 
1641  {
1642  HideWrapper w(pLayout, pStartNd, nStartPos, &sStartText);
1643 
1644  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
1645  *w.m_pText, w.m_nPtIndex,
1646  g_pBreakIt->GetLocale( pStartNd->GetLang( nStartPos ) ) );
1647  }
1648  {
1649  HideWrapper w(pLayout, pEndNd, nEndPos, &sEndText);
1650 
1651  w.m_nPtIndex = g_pBreakIt->GetBreakIter()->endOfSentence(
1652  *w.m_pText, w.m_nPtIndex,
1653  g_pBreakIt->GetLocale( pEndNd->GetLang( nEndPos ) ) );
1654  }
1655 
1656  // it is allowed to place the PaM just behind the last
1657  // character in the text thus <= ...Len
1658  bool bChanged = false;
1659  if (nStartPos <= pStartNd->GetText().getLength() && nStartPos >= 0)
1660  {
1661  *GetMark() = SwPosition(*pStartNd, nStartPos);
1662  bChanged = true;
1663  }
1664  if (nEndPos <= pEndNd->GetText().getLength() && nEndPos >= 0)
1665  {
1666  *GetPoint() = SwPosition(*pEndNd, nEndPos);
1667  bChanged = true;
1668  }
1669  if (bChanged && !IsSelOvr())
1670  bRes = true;
1671  }
1672  return bRes;
1673 }
1674 
1675 bool SwTableCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 /*nMode*/,
1676  bool /*bVisualAllowed*/, bool /*bSkipHidden*/, bool /*bInsertCursor*/,
1677  SwRootFrame const*)
1678 {
1679  return bLeft ? GoPrevCell( nCnt )
1680  : GoNextCell( nCnt );
1681 }
1682 
1683 // calculate cursor bidi level: extracted from LeftRight()
1684 const SwContentFrame*
1686  bool & io_rbLeft, bool bVisualAllowed, bool bInsertCursor)
1687 {
1688  // calculate cursor bidi level
1689  const SwContentFrame* pSttFrame = nullptr;
1690  SwNode& rNode = GetPoint()->nNode.GetNode();
1691 
1692  if( rNode.IsTextNode() )
1693  {
1694  const SwTextNode& rTNd = *rNode.GetTextNode();
1695  SwIndex& rIdx = GetPoint()->nContent;
1696  sal_Int32 nPos = rIdx.GetIndex();
1697 
1698  const SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions();
1699  if ( bVisualAllowed && rCTLOptions.IsCTLFontEnabled() &&
1701  rCTLOptions.GetCTLCursorMovement() )
1702  {
1703  // for visual cursor travelling (used in bidi layout)
1704  // we first have to convert the logic to a visual position
1705  Point aPt;
1706  std::pair<Point, bool> const tmp(aPt, true);
1707  pSttFrame = rTNd.getLayoutFrame(
1708  GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(),
1709  GetPoint(), &tmp);
1710  if( pSttFrame )
1711  {
1712  sal_uInt8 nCursorLevel = GetCursorBidiLevel();
1713  bool bForward = ! io_rbLeft;
1714  SwTextFrame *const pTF(const_cast<SwTextFrame*>(
1715  static_cast<const SwTextFrame*>(pSttFrame)));
1716  TextFrameIndex nTFIndex(pTF->MapModelToViewPos(*GetPoint()));
1717  pTF->PrepareVisualMove( nTFIndex, nCursorLevel,
1718  bForward, bInsertCursor );
1719  *GetPoint() = pTF->MapViewToModelPos(nTFIndex);
1720  SetCursorBidiLevel( nCursorLevel );
1721  io_rbLeft = ! bForward;
1722  }
1723  }
1724  else
1725  {
1726  SwTextFrame const* pFrame;
1727  const SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo(rTNd, &pFrame);
1728  if ( pSI )
1729  {
1730  const sal_Int32 nMoveOverPos = io_rbLeft ?
1731  ( nPos ? nPos - 1 : 0 ) :
1732  nPos;
1733  TextFrameIndex nIndex(pFrame->MapModelToView(&rTNd, nMoveOverPos));
1735  }
1736  }
1737  }
1738  return pSttFrame;
1739 }
1740 
1741 bool SwCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
1742  bool bVisualAllowed,bool bSkipHidden, bool bInsertCursor,
1743  SwRootFrame const*const pLayout)
1744 {
1745  // calculate cursor bidi level
1746  SwNode& rNode = GetPoint()->nNode.GetNode();
1747  const SwContentFrame* pSttFrame = // may side-effect bLeft!
1748  DoSetBidiLevelLeftRight(bLeft, bVisualAllowed, bInsertCursor);
1749 
1750  // can the cursor be moved n times?
1751  SwCursorSaveState aSave( *this );
1752  SwMoveFnCollection const & fnMove = bLeft ? fnMoveBackward : fnMoveForward;
1753 
1754  SwGoInDoc fnGo;
1755  if ( bSkipHidden )
1757  else
1758  fnGo = CRSR_SKIP_CELLS == nMode ? GoInContentCells : GoInContent;
1759 
1760  SwTextFrame const* pFrame(nullptr);
1761  if (pLayout)
1762  {
1763  pFrame = static_cast<SwTextFrame*>(rNode.GetContentNode()->getLayoutFrame(pLayout));
1764  if (pFrame)
1765  {
1766  while (pFrame->GetPrecede())
1767  {
1768  pFrame = static_cast<SwTextFrame const*>(pFrame->GetPrecede());
1769  }
1770  }
1771  }
1772 
1773  while( nCnt )
1774  {
1775  SwNodeIndex aOldNodeIdx( GetPoint()->nNode );
1776 
1777  TextFrameIndex beforeIndex(-1);
1778  if (pFrame)
1779  {
1780  beforeIndex = pFrame->MapModelToViewPos(*GetPoint());
1781  }
1782 
1783  if ( !Move( fnMove, fnGo ) )
1784  break;
1785 
1786  if (pFrame)
1787  {
1788  SwTextFrame const* pNewFrame(static_cast<SwTextFrame const*>(
1789  GetPoint()->nNode.GetNode().GetContentNode()->getLayoutFrame(pLayout)));
1790  if (pNewFrame)
1791  {
1792  while (pNewFrame->GetPrecede())
1793  {
1794  pNewFrame = static_cast<SwTextFrame const*>(pNewFrame->GetPrecede());
1795  }
1796  }
1797  // sw_redlinehide: fully redline-deleted nodes don't have frames...
1798  if (pFrame == pNewFrame || !pNewFrame)
1799  {
1800  if (!pNewFrame || beforeIndex == pFrame->MapModelToViewPos(*GetPoint()))
1801  {
1802  continue; // moving inside delete redline, doesn't count...
1803  }
1804  }
1805  else
1806  {
1807  // assume iteration is stable & returns the same frame
1808  assert(!pFrame->IsAnFollow(pNewFrame) && !pNewFrame->IsAnFollow(pFrame));
1809  pFrame = pNewFrame;
1810  }
1811  }
1812 
1813  // If we were located inside a covered cell but our position has been
1814  // corrected, we check if the last move has moved the cursor to a
1815  // different table cell. In this case we set the cursor to the stored
1816  // covered position and redo the move:
1817  if (m_nRowSpanOffset)
1818  {
1819  const SwNode* pOldTabBoxSttNode = aOldNodeIdx.GetNode().FindTableBoxStartNode();
1820  const SwTableNode* pOldTabSttNode = pOldTabBoxSttNode ? pOldTabBoxSttNode->FindTableNode() : nullptr;
1821  const SwNode* pNewTabBoxSttNode = GetPoint()->nNode.GetNode().FindTableBoxStartNode();
1822  const SwTableNode* pNewTabSttNode = pNewTabBoxSttNode ? pNewTabBoxSttNode->FindTableNode() : nullptr;
1823 
1824  const bool bCellChanged = pOldTabSttNode && pNewTabSttNode &&
1825  pOldTabSttNode == pNewTabSttNode &&
1826  pOldTabBoxSttNode && pNewTabBoxSttNode &&
1827  pOldTabBoxSttNode != pNewTabBoxSttNode;
1828 
1829  if ( bCellChanged )
1830  {
1831  // Set cursor to start/end of covered cell:
1832  SwTableBox* pTableBox = pOldTabBoxSttNode->GetTableBox();
1833  if ( pTableBox && pTableBox->getRowSpan() > 1 )
1834  {
1835  pTableBox = & pTableBox->FindEndOfRowSpan(
1836  pOldTabSttNode->GetTable(),
1837  static_cast<sal_uInt16>(pTableBox->getRowSpan() + m_nRowSpanOffset));
1838  SwNodeIndex& rPtIdx = GetPoint()->nNode;
1839  SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
1840  rPtIdx = aNewIdx;
1841 
1842  GetDoc()->GetNodes().GoNextSection( &rPtIdx, false, false );
1843  SwContentNode* pContentNode = GetContentNode();
1844  if ( pContentNode )
1845  {
1846  GetPoint()->nContent.Assign( pContentNode, bLeft ? pContentNode->Len() : 0 );
1847 
1848  // Redo the move:
1849  if ( !Move( fnMove, fnGo ) )
1850  break;
1851  }
1852  }
1853  m_nRowSpanOffset = 0;
1854  }
1855  }
1856 
1857  // Check if I'm inside a covered cell. Correct cursor if necessary and
1858  // store covered cell:
1859  const SwNode* pTableBoxStartNode = GetPoint()->nNode.GetNode().FindTableBoxStartNode();
1860  if ( pTableBoxStartNode )
1861  {
1862  const SwTableBox* pTableBox = pTableBoxStartNode->GetTableBox();
1863  if ( pTableBox && pTableBox->getRowSpan() < 1 )
1864  {
1865  // Store the row span offset:
1866  m_nRowSpanOffset = pTableBox->getRowSpan();
1867 
1868  // Move cursor to non-covered cell:
1869  const SwTableNode* pTableNd = pTableBoxStartNode->FindTableNode();
1870  pTableBox = & pTableBox->FindStartOfRowSpan( pTableNd->GetTable() );
1871  SwNodeIndex& rPtIdx = GetPoint()->nNode;
1872  SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
1873  rPtIdx = aNewIdx;
1874 
1875  GetDoc()->GetNodes().GoNextSection( &rPtIdx, false, false );
1876  SwContentNode* pContentNode = GetContentNode();
1877  if ( pContentNode )
1878  {
1879  GetPoint()->nContent.Assign( pContentNode, bLeft ? pContentNode->Len() : 0 );
1880  }
1881  }
1882  }
1883  --nCnt;
1884  }
1885 
1886  // here come some special rules for visual cursor travelling
1887  if ( pSttFrame )
1888  {
1889  SwNode& rTmpNode = GetPoint()->nNode.GetNode();
1890  if ( &rTmpNode != &rNode && rTmpNode.IsTextNode() )
1891  {
1892  Point aPt;
1893  std::pair<Point, bool> const tmp(aPt, true);
1894  const SwContentFrame* pEndFrame = rTmpNode.GetTextNode()->getLayoutFrame(
1895  GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(),
1896  GetPoint(), &tmp);
1897  if ( pEndFrame )
1898  {
1899  if ( ! pEndFrame->IsRightToLeft() != ! pSttFrame->IsRightToLeft() )
1900  {
1901  if ( ! bLeft )
1902  pEndFrame->RightMargin( this );
1903  else
1904  pEndFrame->LeftMargin( this );
1905  }
1906  }
1907  }
1908  }
1909 
1910  return 0 == nCnt && !IsInProtectTable( true ) &&
1913 }
1914 
1915 // calculate cursor bidi level: extracted from UpDown()
1917 {
1918  SwNode& rNode = GetPoint()->nNode.GetNode();
1919  if ( !rNode.IsTextNode() )
1920  return;
1921 
1922  SwTextFrame const* pFrame;
1923  const SwScriptInfo* pSI =
1924  SwScriptInfo::GetScriptInfo( *rNode.GetTextNode(), &pFrame );
1925  if ( !pSI )
1926  return;
1927 
1928  SwIndex& rIdx = GetPoint()->nContent;
1929  const sal_Int32 nPos = rIdx.GetIndex();
1930 
1931  if (!(nPos && nPos < rNode.GetTextNode()->GetText().getLength()))
1932  return;
1933 
1934  TextFrameIndex const nIndex(pFrame->MapModelToView(rNode.GetTextNode(), nPos));
1935  const sal_uInt8 nCurrLevel = pSI->DirType( nIndex );
1936  const sal_uInt8 nPrevLevel = pSI->DirType( nIndex - TextFrameIndex(1) );
1937 
1938  if ( nCurrLevel % 2 != nPrevLevel % 2 )
1939  {
1940  // set cursor level to the lower of the two levels
1941  SetCursorBidiLevel( std::min( nCurrLevel, nPrevLevel ) );
1942  }
1943  else
1944  SetCursorBidiLevel( nCurrLevel );
1945 }
1946 
1947 bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
1948  Point const * pPt, long nUpDownX,
1949  SwRootFrame & rLayout)
1950 {
1951  SwTableCursor* pTableCursor = dynamic_cast<SwTableCursor*>(this);
1952  bool bAdjustTableCursor = false;
1953 
1954  // If the point/mark of the table cursor in the same box then set cursor to
1955  // beginning of the box
1956  if( pTableCursor && GetNode().StartOfSectionNode() ==
1957  GetNode( false ).StartOfSectionNode() )
1958  {
1959  if ( End() != GetPoint() )
1960  Exchange();
1961  bAdjustTableCursor = true;
1962  }
1963 
1964  bool bRet = false;
1965  Point aPt;
1966  if( pPt )
1967  aPt = *pPt;
1968  std::pair<Point, bool> const temp(aPt, true);
1969  SwContentFrame* pFrame = GetContentNode()->getLayoutFrame(&rLayout, GetPoint(), &temp);
1970 
1971  if( pFrame )
1972  {
1973  SwCursorSaveState aSave( *this );
1974 
1975  if( !pPt )
1976  {
1977  SwRect aTmpRect;
1978  pFrame->GetCharRect( aTmpRect, *GetPoint() );
1979  aPt = aTmpRect.Pos();
1980 
1981  nUpDownX = pFrame->IsVertical() ?
1982  aPt.getY() - pFrame->getFrameArea().Top() :
1983  aPt.getX() - pFrame->getFrameArea().Left();
1984  }
1985 
1986  // It is allowed to move footnotes in other footnotes but not sections
1987  const bool bChkRange = !pFrame->IsInFootnote() || HasMark();
1988  const SwPosition aOldPos( *GetPoint() );
1989  const bool bInReadOnly = IsReadOnlyAvailable();
1990 
1991  if ( bAdjustTableCursor && !bUp )
1992  {
1993  // Special case: We have a table cursor but the start box has more
1994  // than one paragraph. If we want to go down, we have to set the
1995  // point to the last frame in the table box. This is only necessary
1996  // if we do not already have a table selection
1997  const SwStartNode* pTableNd = GetNode().FindTableBoxStartNode();
1998  OSL_ENSURE( pTableNd, "pTableCursor without SwTableNode?" );
1999 
2000  if ( pTableNd ) // safety first
2001  {
2002  const SwNode* pEndNd = pTableNd->EndOfSectionNode();
2003  GetPoint()->nNode = *pEndNd;
2004  pTableCursor->Move( fnMoveBackward, GoInNode );
2005  std::pair<Point, bool> const tmp(aPt, true);
2006  pFrame = GetContentNode()->getLayoutFrame(&rLayout, GetPoint(), &tmp);
2007  }
2008  }
2009 
2010  while( nCnt &&
2011  (bUp ? pFrame->UnitUp( this, nUpDownX, bInReadOnly )
2012  : pFrame->UnitDown( this, nUpDownX, bInReadOnly ) ) &&
2013  CheckNodesRange( aOldPos.nNode, GetPoint()->nNode, bChkRange ))
2014  {
2015  std::pair<Point, bool> const tmp(aPt, true);
2016  pFrame = GetContentNode()->getLayoutFrame(&rLayout, GetPoint(), &tmp);
2017  --nCnt;
2018  }
2019 
2020  // iterate over whole number of items?
2021  if( !nCnt && !IsSelOvr( SwCursorSelOverFlags::Toggle |
2023  {
2024  if( !pTableCursor )
2025  {
2026  // try to position the cursor at half of the char-rect's height
2027  DisableCallbackAction a(rLayout);
2028  std::pair<Point, bool> const tmp(aPt, true);
2029  pFrame = GetContentNode()->getLayoutFrame(&rLayout, GetPoint(), &tmp);
2031  eTmpState.m_bSetInReadOnly = bInReadOnly;
2032  SwRect aTmpRect;
2033  pFrame->GetCharRect( aTmpRect, *GetPoint(), &eTmpState );
2034  if ( pFrame->IsVertical() )
2035  {
2036  aPt.setX(aTmpRect.Center().getX());
2037  pFrame->Calc(rLayout.GetCurrShell()->GetOut());
2038  aPt.setY(pFrame->getFrameArea().Top() + nUpDownX);
2039  }
2040  else
2041  {
2042  aPt.setY(aTmpRect.Center().getY());
2043  pFrame->Calc(rLayout.GetCurrShell()->GetOut());
2044  aPt.setX(pFrame->getFrameArea().Left() + nUpDownX);
2045  }
2046  pFrame->GetModelPositionForViewPoint( GetPoint(), aPt, &eTmpState );
2047  }
2049  }
2050  else
2051  {
2052  // Jump to beginning or end of line when the cursor at first or last line.
2053  SwNode& rNode = GetPoint()->nNode.GetNode();
2054  const sal_Int32 nOffset = bUp ? 0 : rNode.GetTextNode()->GetText().getLength();
2055  const SwPosition aPos(*GetContentNode(), nOffset);
2056 
2057  //if cursor has already been at start or end of file,
2058  //Update cursor to change nUpDownX.
2059  if ( aOldPos.nContent.GetIndex() == nOffset )
2060  {
2062  bRet = false;
2063  }
2064  else{
2065  *GetPoint() = aPos; // just give a new position
2066  bRet = true;
2067  }
2068 
2069  }
2070 
2071  DoSetBidiLevelUpDown(); // calculate cursor bidi level
2072  }
2073  return bRet;
2074 }
2075 
2076 bool SwCursor::LeftRightMargin(SwRootFrame const& rLayout, bool bLeft, bool bAPI)
2077 {
2078  Point aPt;
2079  std::pair<Point, bool> const tmp(aPt, true);
2080  SwContentFrame const*const pFrame = GetContentNode()->getLayoutFrame(
2081  &rLayout, GetPoint(), &tmp);
2082 
2083  // calculate cursor bidi level
2084  if ( pFrame )
2085  SetCursorBidiLevel( pFrame->IsRightToLeft() ? 1 : 0 );
2086 
2087  SwCursorSaveState aSave( *this );
2088  return pFrame
2089  && (bLeft ? pFrame->LeftMargin( this ) : pFrame->RightMargin( this, bAPI ) )
2091 }
2092 
2093 bool SwCursor::IsAtLeftRightMargin(SwRootFrame const& rLayout, bool bLeft, bool bAPI) const
2094 {
2095  bool bRet = false;
2096  Point aPt;
2097  std::pair<Point, bool> const tmp(aPt, true);
2098  SwContentFrame const*const pFrame = GetContentNode()->getLayoutFrame(
2099  &rLayout, GetPoint(), &tmp);
2100  if( pFrame )
2101  {
2102  SwPaM aPam( *GetPoint() );
2103  if( !bLeft && aPam.GetPoint()->nContent.GetIndex() )
2104  --aPam.GetPoint()->nContent;
2105  bRet = (bLeft ? pFrame->LeftMargin( &aPam )
2106  : pFrame->RightMargin( &aPam, bAPI ))
2107  && (!pFrame->IsTextFrame()
2108  || static_cast<SwTextFrame const*>(pFrame)->MapModelToViewPos(*aPam.GetPoint())
2109  == static_cast<SwTextFrame const*>(pFrame)->MapModelToViewPos(*GetPoint()));
2110  }
2111  return bRet;
2112 }
2113 
2114 bool SwCursor::SttEndDoc( bool bStt )
2115 {
2116  SwCursorSaveState aSave( *this );
2117  // Never jump over section boundaries during selection!
2118  // Can the cursor still moved on?
2119  SwMoveFnCollection const & fnMove = bStt ? fnMoveBackward : fnMoveForward;
2120  bool bRet = (!HasMark() || !IsNoContent() ) &&
2121  Move( fnMove, GoInDoc ) &&
2122  !IsInProtectTable( true ) &&
2126  return bRet;
2127 }
2128 
2129 bool SwCursor::GoPrevNextCell( bool bNext, sal_uInt16 nCnt )
2130 {
2131  const SwTableNode* pTableNd = GetPoint()->nNode.GetNode().FindTableNode();
2132  if( !pTableNd )
2133  return false;
2134 
2135  // If there is another EndNode in front of the cell's StartNode then there
2136  // exists a previous cell
2137  SwCursorSaveState aSave( *this );
2138  SwNodeIndex& rPtIdx = GetPoint()->nNode;
2139 
2140  while( nCnt-- )
2141  {
2142  const SwNode* pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode();
2143  const SwTableBox* pTableBox = pTableBoxStartNode->GetTableBox();
2144 
2145  // Check if we have to move the cursor to a covered cell before
2146  // proceeding:
2147  if (m_nRowSpanOffset)
2148  {
2149  if ( pTableBox && pTableBox->getRowSpan() > 1 )
2150  {
2151  pTableBox = & pTableBox->FindEndOfRowSpan( pTableNd->GetTable(),
2152  static_cast<sal_uInt16>(pTableBox->getRowSpan() + m_nRowSpanOffset));
2153  SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
2154  rPtIdx = aNewIdx;
2155  pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode();
2156  }
2157  m_nRowSpanOffset = 0;
2158  }
2159 
2160  const SwNode* pTmpNode = bNext ?
2161  pTableBoxStartNode->EndOfSectionNode() :
2162  pTableBoxStartNode;
2163 
2164  SwNodeIndex aCellIdx( *pTmpNode, bNext ? 1 : -1 );
2165  if( (bNext && !aCellIdx.GetNode().IsStartNode()) ||
2166  (!bNext && !aCellIdx.GetNode().IsEndNode()) )
2167  return false;
2168 
2169  if (bNext)
2170  rPtIdx = aCellIdx;
2171  else
2172  rPtIdx.Assign(*aCellIdx.GetNode().StartOfSectionNode());
2173 
2174  pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode();
2175  pTableBox = pTableBoxStartNode->GetTableBox();
2176  if ( pTableBox && pTableBox->getRowSpan() < 1 )
2177  {
2178  m_nRowSpanOffset = pTableBox->getRowSpan();
2179  // move cursor to non-covered cell:
2180  pTableBox = & pTableBox->FindStartOfRowSpan( pTableNd->GetTable() );
2181  SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
2182  rPtIdx = aNewIdx;
2183  }
2184  }
2185 
2186  ++rPtIdx;
2187  if( !rPtIdx.GetNode().IsContentNode() )
2188  GetDoc()->GetNodes().GoNextSection( &rPtIdx, true, false );
2190 
2191  return !IsInProtectTable( true );
2192 }
2193 
2194 bool SwTableCursor::GotoTable( const OUString& )
2195 {
2196  return false; // invalid action
2197 }
2198 
2199 bool SwCursor::GotoTable( const OUString& rName )
2200 {
2201  bool bRet = false;
2202  if ( !HasMark() )
2203  {
2204  SwTable* pTmpTable = SwTable::FindTable( GetDoc()->FindTableFormatByName( rName ) );
2205  if( pTmpTable )
2206  {
2207  // a table in a normal nodes array
2208  SwCursorSaveState aSave( *this );
2209  GetPoint()->nNode = *pTmpTable->GetTabSortBoxes()[ 0 ]->
2210  GetSttNd()->FindTableNode();
2212  bRet = !IsSelOvr();
2213  }
2214  }
2215  return bRet;
2216 }
2217 
2218 bool SwCursor::GotoTableBox( const OUString& rName )
2219 {
2220  bool bRet = false;
2221  const SwTableNode* pTableNd = GetPoint()->nNode.GetNode().FindTableNode();
2222  if( pTableNd )
2223  {
2224  // retrieve box by name
2225  const SwTableBox* pTableBox = pTableNd->GetTable().GetTableBox( rName );
2226  if( pTableBox && pTableBox->GetSttNd() &&
2227  ( !pTableBox->GetFrameFormat()->GetProtect().IsContentProtected() ||
2228  IsReadOnlyAvailable() ) )
2229  {
2230  SwCursorSaveState aSave( *this );
2231  GetPoint()->nNode = *pTableBox->GetSttNd();
2233  bRet = !IsSelOvr();
2234  }
2235  }
2236  return bRet;
2237 }
2238 
2239 bool SwCursor::MovePara(SwWhichPara fnWhichPara, SwMoveFnCollection const & fnPosPara )
2240 {
2241  // for optimization test something before
2242  const SwNode* pNd = &GetPoint()->nNode.GetNode();
2243  bool bShortCut = false;
2244  if ( fnWhichPara == GoCurrPara )
2245  {
2246  // #i41048#
2247  // If fnWhichPara == GoCurrPara then (*fnWhichPara)( *this, fnPosPara )
2248  // can already move the cursor to a different text node. In this case
2249  // we better check if IsSelOvr().
2250  const SwContentNode* pContentNd = pNd->GetContentNode();
2251  if ( pContentNd )
2252  {
2253  const sal_Int32 nSttEnd = &fnPosPara == &fnMoveForward ? 0 : pContentNd->Len();
2254  if ( GetPoint()->nContent.GetIndex() != nSttEnd )
2255  bShortCut = true;
2256  }
2257  }
2258  else
2259  {
2260  if ( pNd->IsTextNode() &&
2261  pNd->GetNodes()[ pNd->GetIndex() +
2262  (fnWhichPara == GoNextPara ? 1 : -1 ) ]->IsTextNode() )
2263  bShortCut = true;
2264  }
2265 
2266  if ( bShortCut )
2267  return (*fnWhichPara)( *this, fnPosPara );
2268 
2269  // else we must use the SaveStructure, because the next/prev is not
2270  // a same node type.
2271  SwCursorSaveState aSave( *this );
2272  return (*fnWhichPara)( *this, fnPosPara ) &&
2273  !IsInProtectTable( true ) &&
2276 }
2277 
2279  SwMoveFnCollection const & fnPosSect)
2280 {
2281  SwCursorSaveState aSave( *this );
2282  return (*fnWhichSect)( *this, fnPosSect ) &&
2283  !IsInProtectTable( true ) &&
2286 }
2287 
2289 {
2290  // This method is not supposed to be used in cases when nodes may be
2291  // deleted; detect such cases, but do not crash (example: fdo#40831).
2292  sal_uLong uNodeCount = GetPoint()->nNode.GetNodes().Count();
2293  OSL_ENSURE(m_vSavePos.empty() || m_vSavePos.back().nNode < uNodeCount,
2294  "SwCursor::RestoreSavePos: invalid node: "
2295  "probably something was deleted; consider using SwUnoCursor instead");
2296  if (m_vSavePos.empty() || m_vSavePos.back().nNode >= uNodeCount)
2297  return;
2298 
2299  GetPoint()->nNode = m_vSavePos.back().nNode;
2300 
2301  sal_Int32 nIdx = 0;
2302  if ( GetContentNode() )
2303  {
2304  if (m_vSavePos.back().nContent <= GetContentNode()->Len())
2305  nIdx = m_vSavePos.back().nContent;
2306  else
2307  {
2308  nIdx = GetContentNode()->Len();
2309  OSL_FAIL("SwCursor::RestoreSavePos: invalid content index");
2310  }
2311  }
2312  GetPoint()->nContent.Assign( GetContentNode(), nIdx );
2313 }
2314 
2316  : SwCursor( rPos, nullptr )
2317 {
2318  m_bParked = false;
2319  m_bChanged = false;
2320  m_nTablePtNd = 0;
2321  m_nTableMkNd = 0;
2322  m_nTablePtCnt = 0;
2323  m_nTableMkCnt = 0;
2324 }
2325 
2327 
2328 static bool
2329 lcl_SeekEntry(const SwSelBoxes& rTmp, SwStartNode const*const pSrch,
2330  size_t & o_rFndPos)
2331 {
2332  sal_uLong nIdx = pSrch->GetIndex();
2333 
2334  size_t nO = rTmp.size();
2335  if( nO > 0 )
2336  {
2337  nO--;
2338  size_t nU = 0;
2339  while( nU <= nO )
2340  {
2341  size_t nM = nU + ( nO - nU ) / 2;
2342  if( rTmp[ nM ]->GetSttNd() == pSrch )
2343  {
2344  o_rFndPos = nM;
2345  return true;
2346  }
2347  else if( rTmp[ nM ]->GetSttIdx() < nIdx )
2348  nU = nM + 1;
2349  else if( nM == 0 )
2350  return false;
2351  else
2352  nO = nM - 1;
2353  }
2354  }
2355  return false;
2356 }
2357 
2359 {
2360  if (m_bChanged)
2361  {
2362  if (m_bParked)
2363  {
2364  // move back into content
2365  Exchange();
2366  Move( fnMoveForward );
2367  Exchange();
2368  Move( fnMoveForward );
2369  m_bParked = false;
2370  }
2371 
2372  m_bChanged = false;
2373 
2374  // create temporary copies so that all boxes that
2375  // have already cursors can be removed
2377 
2378  // compare old and new ones
2379  SwNodes& rNds = pCurrentCursor->GetDoc()->GetNodes();
2380  const SwStartNode* pSttNd;
2381  SwPaM* pCur = pCurrentCursor;
2382  do {
2383  size_t nPos;
2384  bool bDel = false;
2385  pSttNd = pCur->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
2386  if( !pCur->HasMark() || !pSttNd ||
2387  pSttNd != pCur->GetMark()->nNode.GetNode().FindTableBoxStartNode() )
2388  bDel = true;
2389 
2390  else if( lcl_SeekEntry( aTmp, pSttNd, nPos ))
2391  {
2392  SwNodeIndex aIdx( *pSttNd, 1 );
2393  const SwNode* pNd = &aIdx.GetNode();
2394  if( !pNd->IsContentNode() )
2395  pNd = rNds.GoNextSection( &aIdx, true, false );
2396 
2397  SwPosition* pPos = pCur->GetMark();
2398  if( pNd != &pPos->nNode.GetNode() )
2399  pPos->nNode = *pNd;
2400  pPos->nContent.Assign( const_cast<SwContentNode*>(static_cast<const SwContentNode*>(pNd)), 0 );
2401 
2402  aIdx.Assign( *pSttNd->EndOfSectionNode(), - 1 );
2403  pNd = &aIdx.GetNode();
2404  if( !pNd->IsContentNode() )
2405  pNd = SwNodes::GoPrevSection( &aIdx, true, false );
2406 
2407  pPos = pCur->GetPoint();
2408  if (pNd && pNd != &pPos->nNode.GetNode())
2409  pPos->nNode = *pNd;
2410  pPos->nContent.Assign(const_cast<SwContentNode*>(static_cast<const SwContentNode*>(pNd)), pNd ? static_cast<const SwContentNode*>(pNd)->Len() : 0);
2411 
2412  aTmp.erase( aTmp.begin() + nPos );
2413  }
2414  else
2415  bDel = true;
2416 
2417  pCur = pCur->GetNext();
2418  if( bDel )
2419  {
2420  SwPaM* pDel = pCur->GetPrev();
2421 
2422  if( pDel == pCurrentCursor )
2423  pCurrentCursor->DeleteMark();
2424  else
2425  delete pDel;
2426  }
2427  } while ( pCurrentCursor != pCur );
2428 
2429  for (size_t nPos = 0; nPos < aTmp.size(); ++nPos)
2430  {
2431  pSttNd = aTmp[ nPos ]->GetSttNd();
2432 
2433  SwNodeIndex aIdx( *pSttNd, 1 );
2434  if( &aIdx.GetNodes() != &rNds )
2435  break;
2436  SwNode* pNd = &aIdx.GetNode();
2437  if( !pNd->IsContentNode() )
2438  pNd = rNds.GoNextSection( &aIdx, true, false );
2439 
2440  SwPaM *const pNew = (!pCurrentCursor->IsMultiSelection() && !pCurrentCursor->HasMark())
2441  ? pCurrentCursor
2442  : pCurrentCursor->Create( pCurrentCursor );
2443  pNew->GetPoint()->nNode = *pNd;
2444  pNew->GetPoint()->nContent.Assign( static_cast<SwContentNode*>(pNd), 0 );
2445  pNew->SetMark();
2446 
2447  SwPosition* pPos = pNew->GetPoint();
2448  pPos->nNode.Assign( *pSttNd->EndOfSectionNode(), - 1 );
2449  pNd = &pPos->nNode.GetNode();
2450  if( !pNd->IsContentNode() )
2451  pNd = SwNodes::GoPrevSection( &pPos->nNode, true, false );
2452 
2453  pPos->nContent.Assign(static_cast<SwContentNode*>(pNd), pNd ? static_cast<SwContentNode*>(pNd)->Len() : 0);
2454  }
2455  }
2456  return pCurrentCursor;
2457 }
2458 
2459 void SwTableCursor::InsertBox( const SwTableBox& rTableBox )
2460 {
2461  SwTableBox* pBox = const_cast<SwTableBox*>(&rTableBox);
2462  m_SelectedBoxes.insert(pBox);
2463  m_bChanged = true;
2464 }
2465 
2466 void SwTableCursor::DeleteBox(size_t const nPos)
2467 {
2469  m_bChanged = true;
2470 }
2471 
2473 {
2474  bool bRet = false;
2475  const SwNode *pStart = GetNode().FindTableBoxStartNode();
2476  const SwNode *pEnd = GetNode(false).FindTableBoxStartNode();
2477  if( pStart && pEnd )
2478  {
2479  const SwTableNode *pTableNode = pStart->FindTableNode();
2480  if( pTableNode == pEnd->FindTableNode() &&
2481  pTableNode->GetTable().IsNewModel() )
2482  {
2483  bRet = true;
2485  pTableNode->GetTable().CreateSelection( pStart, pEnd, aNew,
2486  SwTable::SEARCH_NONE, false );
2487  ActualizeSelection( aNew );
2488  }
2489  }
2490  return bRet;
2491 }
2492 
2494 {
2495  size_t nOld = 0, nNew = 0;
2496  while (nOld < m_SelectedBoxes.size() && nNew < rNew.size())
2497  {
2498  SwTableBox const*const pPOld = m_SelectedBoxes[ nOld ];
2499  const SwTableBox* pPNew = rNew[ nNew ];
2500  if( pPOld == pPNew )
2501  { // this box will stay
2502  ++nOld;
2503  ++nNew;
2504  }
2505  else if( pPOld->GetSttIdx() < pPNew->GetSttIdx() )
2506  {
2507  DeleteBox( nOld ); // this box has to go
2508  }
2509  else
2510  {
2511  InsertBox( *pPNew ); // this is a new one
2512  ++nOld;
2513  ++nNew;
2514  }
2515  }
2516 
2517  while (nOld < m_SelectedBoxes.size())
2518  {
2519  DeleteBox( nOld ); // some more to delete
2520  }
2521 
2522  for ( ; nNew < rNew.size(); ++nNew ) // some more to insert
2523  {
2524  InsertBox( *rNew[ nNew ] );
2525  }
2526 }
2527 
2529 {
2530  if( !IsCursorMoved() )
2531  return false;
2532 
2537  return true;
2538 }
2539 
2542 {
2543  // de-register index from text node
2544  SwNode* pNd = &GetPoint()->nNode.GetNode();
2545  if( !pNd->IsStartNode() )
2546  pNd = pNd->StartOfSectionNode();
2547  GetPoint()->nNode = *pNd;
2548  GetPoint()->nContent.Assign( nullptr, 0 );
2549 
2550  pNd = &GetMark()->nNode.GetNode();
2551  if( !pNd->IsStartNode() )
2552  pNd = pNd->StartOfSectionNode();
2553  GetMark()->nNode = *pNd;
2554  GetMark()->nContent.Assign( nullptr, 0 );
2555 
2556  m_bChanged = true;
2557  m_bParked = true;
2558 }
2559 
2561 {
2562  bool bRet = false;
2563  for (size_t n = m_SelectedBoxes.size(); n; )
2564  {
2565  if (m_SelectedBoxes[--n]->GetFrameFormat()->GetProtect().IsContentProtected())
2566  {
2567  bRet = true;
2568  break;
2569  }
2570  }
2571  return bRet;
2572 }
2573 
2574 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool SttEndDoc(bool bSttDoc)
Definition: swcrsr.cxx:2114
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:339
bool GoSentence(SentenceMoveType eMoveType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1553
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:961
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
Starts a section of nodes in the document model.
Definition: node.hxx:303
bool MovePara(SwWhichPara, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2239
bool IsCursorMoved() const
Definition: swcrsr.hxx:288
void merge(RingContainer< value_type > aDestRing)
Merges two ring containers.
Definition: ring.hxx:182
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
virtual sal_Int32 Len() const
Definition: node.cxx:1223
static bool lcl_SeekEntry(const SwSelBoxes &rTmp, SwStartNode const *const pSrch, size_t &o_rFndPos)
Definition: swcrsr.cxx:2329
void DeleteMark()
Definition: pam.hxx:177
void CreateSelection(const SwPaM &rPam, SwSelBoxes &rBoxes, const SearchType eSearchType, bool bProtect) const
void SwTable::CreateSelection(..) fills the selection structure with table cells for a given SwPaM...
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:1566
void InsertBox(const SwTableBox &rTableBox)
Definition: swcrsr.cxx:2459
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
SwCursorSelOverFlags
Definition: swcrsr.hxx:47
sal_Int32 nIndex
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:963
SwTableCursor(const SwPosition &rPos)
Definition: swcrsr.cxx:2315
sal_uLong Count() const
Definition: ndarr.hxx:142
bool IsStartEndSentence(bool bEnd, SwRootFrame const *pLayout) const
Definition: swcrsr.cxx:1275
Marks a position in the document model.
Definition: pam.hxx:35
bool IsInProtectTable(bool bMove=false, bool bChgCursor=true)
Definition: swcrsr.cxx:565
bool IsSectionNode() const
Definition: node.hxx:644
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:98
bool IsMultiSelection() const
Definition: pam.hxx:272
void FillFindPos(SwDocPositions ePos, SwPosition &rPos) const
Definition: swcrsr.cxx:1102
const SwTableBox * GetTableBox(const OUString &rName, const bool bPerformValidCheck=false) const
Definition: swtable.cxx:1345
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:749
bool GoEndWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1320
bool GoPrevCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:173
const OUString & GetText() const
Definition: ndtxt.hxx:211
virtual const SwRootFrame * GetCurrentLayout() const =0
sal_uLong GetSttIdx() const
Definition: swtable.cxx:1883
bool MoveSection(SwWhichSection, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2278
SwDocShell * GetDocShell()
Definition: doc.hxx:1348
bool GoCurrPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1009
virtual short MaxReplaceArived()
Definition: swcrsr.cxx:1138
bool IsAtLeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI) const
Definition: swcrsr.cxx:2093
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsInFootnote() const
Definition: frame.hxx:927
sal_uIntPtr sal_uLong
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:474
const SwPosition * GetMark() const
Definition: pam.hxx:209
Find "all" in Footer/Header/Fly...
bool IsEndWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr) const
Definition: swcrsr.cxx:1225
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1190
sal_Int64 n
Provides access to the marks of a document.
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:223
Definition: doc.hxx:184
static SwContentNode * GoPrevSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true)
Definition: nodes.cxx:1958
SentenceMoveType
Definition: swcrsr.hxx:151
helper class to disable creation of an action by a callback event in particular, change event from a ...
Definition: rootfrm.hxx:441
bool m_bSetInReadOnly
ReadOnly areas may be entered.
Definition: crstate.hxx:148
void Height(long nNew)
Definition: swrect.hxx:191
virtual SwCursor * Create(SwPaM *pRing=nullptr) const
Definition: swcrsr.cxx:146
static SwScriptInfo * GetScriptInfo(const SwTextNode &rNode, SwTextFrame const **o_pFrame=nullptr, bool bAllowInvalid=false)
return a frame for the node, ScriptInfo is its member...
Definition: porlay.cxx:2341
sal_uLong m_nTableMkNd
Definition: swcrsr.hxx:256
SwPosition FindFieldSep(IFieldmark const &rMark)
return position of the CH_TXT_ATR_FIELDSEP for rMark
Definition: bookmrk.cxx:57
sal_uInt8 GetCursorBidiLevel() const
Definition: swcrsr.hxx:209
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1300
SwNode & GetNode() const
Definition: ndindex.hxx:119
SwCursor * MakeBoxSels(SwCursor *pCurrentCursor)
Definition: swcrsr.cxx:2358
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:31
void EndProgress(SwDocShell const *pDocShell)
Definition: mainwn.cxx:92
void Pos(const Point &rNew)
Definition: swrect.hxx:169
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1682
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:143
SwNode & GetEndOfPostIts() const
A still empty section.
Definition: ndarr.hxx:152
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1787
long m_nRowSpanOffset
Definition: swcrsr.hxx:73
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
virtual ~SwCursor() override
Definition: swcrsr.cxx:142
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1283
SwTextAttr * GetTextAttrAt(sal_Int32 const nIndex, sal_uInt16 const nWhich, enum GetTextAttrMode const eMode=DEFAULT) const
get the innermost text attribute covering position nIndex.
Definition: ndtxt.cxx:1722
bool IsCTLFontEnabled() const
virtual bool LeftMargin(SwPaM *) const =0
virtual bool LeftRight(bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, SwRootFrame const *pLayout)
Definition: swcrsr.cxx:1741
void CalcStartEnd(sal_uLong nNdIdx, sal_Int32 &rStart, sal_Int32 &rEnd) const
Calculates the intersection with text node number nNdIdx.
Definition: docredln.cxx:1270
The root element of a Writer document layout.
Definition: rootfrm.hxx:80
RET_CANCEL
bool IsReadOnlyUI() const
sal_uInt8 DirType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1655
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:169
Find in selections.
bool SelectWord(SwViewShell const *pViewShell, const Point *pPt)
Definition: swcrsr.cxx:1202
static bool IsShowChanges(const RedlineFlags eM)
virtual bool IsSkipOverHiddenSections() const
Definition: swcrsr.cxx:156
Array of Undo-history.
Definition: docary.hxx:197
SwDocPositions
Definition: cshtyp.hxx:103
const SwSection & GetSection() const
Definition: node.hxx:541
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:46
sal_uLong m_nTablePtNd
Definition: swcrsr.hxx:255
bool isLetterNumeric(const OUString &rStr, sal_Int32 nPos) const
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Primary passes the call to the first page.
Definition: trvlfrm.cxx:424
virtual bool IsSelOvrCheck(SwCursorSelOverFlags eFlags)
Definition: swcrsr.cxx:188
#define CH_TXTATR_INWORD
Definition: hintids.hxx:171
SwTableNode * GetTableNode()
Definition: node.hxx:599
RET_YES
void Top(const long nTop)
Definition: swrect.hxx:204
void StartProgress(const char *pMessResId, long nStartValue, long nEndValue, SwDocShell *pDocShell)
Definition: mainwn.cxx:52
SwIndex nContent
Definition: pam.hxx:38
const SwRect & getFrameArea() const
Definition: frame.hxx:177
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
Cursor Up/Down.
size_t pos
auto(*)(SwPaM &rPam, SwMoveFnCollection const &fnMove) -> bool SwGoInDoc
Definition: pam.hxx:126
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &pos) const =0
static OUString lcl_MaskDeletedRedlines(const SwTextNode *pTextNd)
Definition: swcrsr.cxx:1520
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
bool GoPrevWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1378
static sal_uLong lcl_FindSelection(SwFindParas &rParas, SwCursor *pCurrentCursor, SwMoveFnCollection const &fnMove, SwCursor *&pFndRing, SwPaM &aRegion, FindRanges eFndRngs, bool bInReadOnly, bool &bCancel)
Definition: swcrsr.cxx:760
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
virtual void DelAllUndoObj()=0
Delete all Undo actions.
virtual bool GotoTable(const OUString &rName) override
Definition: swcrsr.cxx:2194
FindRanges
Definition: cshtyp.hxx:90
bool IsTextFrame() const
Definition: frame.hxx:1212
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:965
virtual void DoUndo(bool const bDoUndo)=0
Enable/Disable Undo.
bool IsStartNode() const
Definition: node.hxx:624
bool IsCursorMovedUpdate()
Definition: swcrsr.cxx:2528
virtual void DoSetBidiLevelUpDown()
Definition: swcrsr.cxx:1916
std::vector< SwCursor_SavePos > m_vSavePos
Definition: swcrsr.hxx:72
CursorMovement GetCTLCursorMovement() const
bool CheckNodesRange(const SwNodeIndex &rStt, const SwNodeIndex &rEnd, bool bChkSection)
Check if the given range is inside one of the defined top-level sections.
Definition: pam.cxx:256
const SwTable & GetTable() const
Definition: node.hxx:497
bool SelectWordWT(SwViewShell const *pViewShell, sal_Int16 nWordType, const Point *pPt)
Definition: swcrsr.cxx:1413
bool IsProtectFlag() const
Definition: section.hxx:188
SwContentFrame * GetPrevContentFrame() const
Definition: cntfrm.hxx:106
SwMoveFnCollection const & MakeFindRange(SwDocPositions, SwDocPositions, SwPaM *) const
set range for search in document
Definition: swcrsr.cxx:746
virtual bool UnitDown(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:970
size_type size() const
virtual bool DoesUndo() const =0
Is Undo enabled?
virtual bool GotoTable(const OUString &rName)
Definition: swcrsr.cxx:2199
SwPaM * GetNext()
Definition: pam.hxx:264
void SetProgressState(long nPosition, SwDocShell const *pDocShell)
Definition: mainwn.cxx:82
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:71
void SaveState()
Definition: swcrsr.cxx:168
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:163
bool GoNextCell(sal_uInt16 nCnt=1)
Definition: swcrsr.hxx:172
SwTableSortBoxes & GetTabSortBoxes()
Definition: swtable.hxx:259
bool IsContentNode() const
Definition: node.hxx:628
OUString GetText() const
Definition: pam.cxx:1069
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:501
static SwTable * FindTable(SwFrameFormat const *const pFormat)
Definition: swtable.cxx:1923
sal_Int32 m_nTablePtCnt
Definition: swcrsr.hxx:257
virtual bool IsReplaceMode() const =0
bool m_bChanged
Definition: swcrsr.hxx:260
A helper class to save cursor state (position).
Definition: swcrsr.hxx:230
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1259
#define SW_MOD()
Definition: swmodule.hxx:255
sal_uLong FindAll(SwFindParas &, SwDocPositions, SwDocPositions, FindRanges, bool &bCancel)
Definition: swcrsr.cxx:950
bool(* SwWhichPara)(SwPaM &, SwMoveFnCollection const &)
Definition: cshtyp.hxx:43
SwCursor * GetNext()
Definition: swcrsr.hxx:217
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:954
uno_Any a
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
const SwPosition * GetPoint() const
Definition: pam.hxx:207
std::vector< SwSectionFormat * >::size_type size_type
Definition: docary.hxx:63
bool GoInContentCells(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:971
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:327
bool GoNextWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1350
bool IsInWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr) const
Definition: swcrsr.cxx:1244
bool GoInContentCellsSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:987
void Exchange()
Definition: pam.cxx:489
bool IsHiddenFlag() const
Definition: section.hxx:187
SwContentNode * GetContentNode()
Definition: node.hxx:615
vector_type::size_type size_type
Definition: docary.hxx:228
void MakeStartIndex(SwIndex *pIdx)
Definition: node.hxx:391
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
SwDoc * GetDoc()
Definition: node.hxx:702
SwDoc * GetDoc() const
Definition: pam.hxx:243
All (only in non-body and selections).
Marks a character position inside a document model node.
Definition: index.hxx:33
size_t size() const
Definition: docary.hxx:84
bool IsNoContent() const
determine if point is outside of the node-array's content area
Definition: swcrsr.cxx:182
sal_Int32 w
bool IsContentProtected() const
Marks a node in the document model.
Definition: ndindex.hxx:31
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:425
bool IsEndNode() const
Definition: node.hxx:632
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
bool GoInDoc(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:942
ring_container GetRingContainer()
Definition: ring.hxx:240
const sal_uInt16 coSrchRplcThreshold
Definition: swcrsr.cxx:61
virtual bool RightMargin(SwPaM *, bool bAPI=false) const =0
static bool lcl_MakeSelBkwrd(const SwNode &rSttNd, const SwNode &rEndNd, SwPaM &rPam, bool bFirst)
Definition: swcrsr.cxx:917
bool IsProtect() const
Is node in something that is protected (range, frame, table cells ...
Definition: node.cxx:421
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1223
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 int FIND_NO_RING
Definition: swcrsr.hxx:36
const SwPosition * Start() const
Definition: pam.hxx:212
virtual bool IsSkipOverProtectSections() const
Definition: swcrsr.cxx:161
virtual const SwContentFrame * DoSetBidiLevelLeftRight(bool &io_rbLeft, bool bVisualAllowed, bool bInsertCursor)
Definition: swcrsr.cxx:1685
EXPAND : (Start < nIndex <= End)
Definition: ndtxt.hxx:364
Find only in body - only in combination with FindRanges::InSelAll !!!
Point Center() const
Definition: swrect.cxx:35
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
const_iterator begin() const
SwPaM * GetPrev()
Definition: pam.hxx:268
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:62
bool GoInContentSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:979
void RestoreState()
Definition: swcrsr.cxx:173
virtual bool IsReadOnlyAvailable() const
Definition: swcrsr.cxx:151
const sal_uInt16 CRSR_SKIP_CELLS
Definition: swcrsr.hxx:64
const css::lang::Locale & GetLocale(const LanguageType aLang)
Definition: breakit.hxx:67
void Left(const long nLeft)
Definition: swrect.hxx:195
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
bool LeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI)
Definition: swcrsr.cxx:2076
SwSelBoxes m_SelectedBoxes
Definition: swcrsr.hxx:259
virtual sw::mark::IMark * getAnnotationMarkFor(const SwPosition &rPosition) const =0
bool GotoTableBox(const OUString &rName)
Definition: swcrsr.cxx:2218
const SwFlowFrame * GetPrecede() const
Definition: flowfrm.hxx:172
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:439
virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool)=0
virtual bool LeftRight(bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, SwRootFrame const *) override
Definition: swcrsr.cxx:1675
SwTableBox & FindStartOfRowSpan(const SwTable &, sal_uInt16 nMaxStep=USHRT_MAX)
SwTableBox::FindStartOfRowSpan(..) returns the "master" cell, the cell which overlaps the given cell...
long getRowSpan() const
Definition: swtable.cxx:101
bool UpDown(bool bUp, sal_uInt16 nCnt, Point const *pPt, long nUpDownX, SwRootFrame &rLayout)
Definition: swcrsr.cxx:1947
unsigned char sal_uInt8
const SwNodes & GetNodes() const
Definition: ndindex.hxx:156
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
bool ExpandToSentenceBorders(SwRootFrame const *pLayout)
Definition: swcrsr.cxx:1624
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1244
sal_Int32 GetIndex() const
Definition: index.hxx:91
bool IsNoTextFrame() const
Definition: frame.hxx:1216
SwNodes & GetNodes()
Definition: doc.hxx:403
bool m_bParked
Definition: swcrsr.hxx:261
const SwPosition * End() const
Definition: pam.hxx:217
void SetCursorBidiLevel(sal_uInt8 nNewLevel)
Definition: swcrsr.hxx:210
bool IsRightToLeft() const
Definition: frame.hxx:965
LanguageType GetLang(const sal_Int32 nBegin, const sal_Int32 nLen=0, sal_uInt16 nScript=0) const
Definition: thints.cxx:3402
SwCursor(SwCursor const &rPaM)=delete
SwTableBox & FindEndOfRowSpan(const SwTable &, sal_uInt16 nMaxStep)
SwTableBox::FindEndOfRowSpan(..) returns the last overlapped cell if there is any.
bool GoNextPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1037
bool GoPrevNextCell(bool bNext, sal_uInt16 nCnt)
Definition: swcrsr.cxx:2129
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1734
const sal_Int32 * End() const
Definition: txatbase.hxx:148
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
virtual ~SwTableCursor() override
Definition: swcrsr.cxx:2326
double getLength(const B2DPolygon &rCandidate)
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:417
bool IsAnFollow(const SwFlowFrame *pFlow) const
Definition: flowfrm.cxx:670
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
void PrepareVisualMove(TextFrameIndex &nPos, sal_uInt8 &nCursorLevel, bool &bRight, bool bInsertCursor)
Prepares the cursor position for a visual cursor move (BiDi).
Definition: frmcrsr.cxx:1041
void ParkCursor()
park table cursor on the boxes' start node
Definition: swcrsr.cxx:2541
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:196
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:352
Find "one" only in body text.
virtual bool IsAtValidPos(bool bPoint=true) const
Return if cursor can be set to this position.
Definition: swcrsr.cxx:717
virtual bool IsSelOvrCheck(SwCursorSelOverFlags eFlags) override
Definition: swcrsr.cxx:194
bool IsVertical() const
Definition: frame.hxx:951
sal_Int32 m_nTableMkCnt
Definition: swcrsr.hxx:258
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:1906
void ActualizeSelection(const SwSelBoxes &rBoxes)
Definition: swcrsr.cxx:2493
bool IsTableNode() const
Definition: node.hxx:640
const SvxProtectItem & GetProtect(bool=true) const
Definition: frmatr.hxx:82
static bool lcl_MakeSelFwrd(const SwNode &rSttNd, const SwNode &rEndNd, SwPaM &rPam, bool bFirst)
Definition: swcrsr.cxx:885
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:475
SectionType GetType() const
Definition: section.hxx:170
void DeleteBox(size_t nPos)
Definition: swcrsr.cxx:2466
SwSection * GetSection() const
Definition: section.cxx:671
std::pair< const_iterator, bool > insert(Value &&x)
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:161
bool IsNewModel() const
Definition: swtable.hxx:185
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2069
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:205
SwSectionFormats & GetSections()
Definition: doc.hxx:1334
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 NewTableSelection()
Definition: swcrsr.cxx:2472
CharClass & GetAppCharClass()
Definition: init.cxx:708
bool IsTextNode() const
Definition: node.hxx:636
bool HasReadOnlyBoxSel() const
Definition: swcrsr.cxx:2560
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1238
virtual void SaveTableBoxContent(const SwPosition *pPos)
Definition: swcrsr.cxx:743
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1283
void MakeEndIndex(SwIndex *pIdx)
Definition: node.hxx:392
bool(* SwWhichSection)(SwPaM &, SwMoveFnCollection const &)
Definition: cshtyp.hxx:51
bool IsStartWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr) const
Definition: swcrsr.cxx:1207
sal_uInt16 nPos
bool GoStartWordWT(sal_Int16 nWordType, SwRootFrame const *pLayout=nullptr)
Definition: swcrsr.cxx:1291
void RestoreSavePos()
Restore cursor state to the one saved by SwCursorSaveState.
Definition: swcrsr.cxx:2288
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:844
size_type erase(const Value &x)
SwNodeIndex & Assign(SwNodes const &rNds, sal_uLong)
Definition: ndindex.hxx:272
SwCursor * GetPrev()
Definition: swcrsr.hxx:219
Base class of the Writer document model elements.
Definition: node.hxx:79
const SwCursor_SavePos * GetSavePos() const
Definition: swcrsr.hxx:85