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