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->HasMergedParas())
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->HasMergedParas()) || !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 (!bLeft && pLayout && pLayout->GetFieldmarkMode() == sw::FieldmarkMode::ShowResult)
1787  {
1788  SwTextNode const*const pNode(GetPoint()->nNode.GetNode().GetTextNode());
1789  assert(pNode);
1790  if (pNode->Len() != GetPoint()->nContent.GetIndex()
1791  && pNode->GetText()[GetPoint()->nContent.GetIndex()] == CH_TXT_ATR_FIELDSTART)
1792  {
1793  IDocumentMarkAccess const& rIDMA(*GetDoc().getIDocumentMarkAccess());
1794  sw::mark::IFieldmark const*const pMark(rIDMA.getFieldmarkAt(*GetPoint()));
1795  assert(pMark);
1796  *GetPoint() = sw::mark::FindFieldSep(*pMark);
1797  }
1798  }
1799 
1800  if ( !Move( fnMove, fnGo ) )
1801  break;
1802 
1803  if (pFrame)
1804  {
1805  SwTextFrame const* pNewFrame(static_cast<SwTextFrame const*>(
1806  GetPoint()->nNode.GetNode().GetContentNode()->getLayoutFrame(pLayout)));
1807  if (pNewFrame)
1808  {
1809  while (pNewFrame->GetPrecede())
1810  {
1811  pNewFrame = static_cast<SwTextFrame const*>(pNewFrame->GetPrecede());
1812  }
1813  }
1814  // sw_redlinehide: fully redline-deleted nodes don't have frames...
1815  if (pFrame == pNewFrame || !pNewFrame)
1816  {
1817  if (!pNewFrame || beforeIndex == pFrame->MapModelToViewPos(*GetPoint()))
1818  {
1819  continue; // moving inside delete redline, doesn't count...
1820  }
1821  }
1822  else
1823  {
1824  // assume iteration is stable & returns the same frame
1825  assert(!pFrame->IsAnFollow(pNewFrame) && !pNewFrame->IsAnFollow(pFrame));
1826  pFrame = pNewFrame;
1827  }
1828  }
1829 
1830  if (bLeft && pLayout && pLayout->GetFieldmarkMode() == sw::FieldmarkMode::ShowCommand)
1831  {
1832  SwTextNode const*const pNode(GetPoint()->nNode.GetNode().GetTextNode());
1833  assert(pNode);
1834  if (pNode->Len() != GetPoint()->nContent.GetIndex()
1835  && pNode->GetText()[GetPoint()->nContent.GetIndex()] == CH_TXT_ATR_FIELDEND)
1836  {
1837  IDocumentMarkAccess const& rIDMA(*GetDoc().getIDocumentMarkAccess());
1838  sw::mark::IFieldmark const*const pMark(rIDMA.getFieldmarkAt(*GetPoint()));
1839  assert(pMark);
1840  *GetPoint() = sw::mark::FindFieldSep(*pMark);
1841  }
1842  }
1843 
1844  if (isFieldNames)
1845  {
1846  SwTextNode const*const pNode(GetPoint()->nNode.GetNode().GetTextNode());
1847  assert(pNode);
1848  SwTextAttr const*const pInputField(pNode->GetTextAttrAt(
1849  GetPoint()->nContent.GetIndex(), RES_TXTATR_INPUTFIELD, SwTextNode::PARENT));
1850  if (pInputField)
1851  {
1852  continue; // skip over input fields
1853  }
1854  }
1855 
1856  // If we were located inside a covered cell but our position has been
1857  // corrected, we check if the last move has moved the cursor to a
1858  // different table cell. In this case we set the cursor to the stored
1859  // covered position and redo the move:
1860  if (m_nRowSpanOffset)
1861  {
1862  const SwNode* pOldTabBoxSttNode = aOldNodeIdx.GetNode().FindTableBoxStartNode();
1863  const SwTableNode* pOldTabSttNode = pOldTabBoxSttNode ? pOldTabBoxSttNode->FindTableNode() : nullptr;
1864  const SwNode* pNewTabBoxSttNode = GetPoint()->nNode.GetNode().FindTableBoxStartNode();
1865  const SwTableNode* pNewTabSttNode = pNewTabBoxSttNode ? pNewTabBoxSttNode->FindTableNode() : nullptr;
1866 
1867  const bool bCellChanged = pOldTabSttNode && pNewTabSttNode &&
1868  pOldTabSttNode == pNewTabSttNode &&
1869  pOldTabBoxSttNode && pNewTabBoxSttNode &&
1870  pOldTabBoxSttNode != pNewTabBoxSttNode;
1871 
1872  if ( bCellChanged )
1873  {
1874  // Set cursor to start/end of covered cell:
1875  SwTableBox* pTableBox = pOldTabBoxSttNode->GetTableBox();
1876  if ( pTableBox && pTableBox->getRowSpan() > 1 )
1877  {
1878  pTableBox = & pTableBox->FindEndOfRowSpan(
1879  pOldTabSttNode->GetTable(),
1880  static_cast<sal_uInt16>(pTableBox->getRowSpan() + m_nRowSpanOffset));
1881  SwNodeIndex& rPtIdx = GetPoint()->nNode;
1882  SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
1883  rPtIdx = aNewIdx;
1884 
1885  GetDoc().GetNodes().GoNextSection( &rPtIdx, false, false );
1886  SwContentNode* pContentNode = GetContentNode();
1887  if ( pContentNode )
1888  {
1889  GetPoint()->nContent.Assign( pContentNode, bLeft ? pContentNode->Len() : 0 );
1890 
1891  // Redo the move:
1892  if ( !Move( fnMove, fnGo ) )
1893  break;
1894  }
1895  }
1896  m_nRowSpanOffset = 0;
1897  }
1898  }
1899 
1900  // Check if I'm inside a covered cell. Correct cursor if necessary and
1901  // store covered cell:
1902  const SwNode* pTableBoxStartNode = GetPoint()->nNode.GetNode().FindTableBoxStartNode();
1903  if ( pTableBoxStartNode )
1904  {
1905  const SwTableBox* pTableBox = pTableBoxStartNode->GetTableBox();
1906  if ( pTableBox && pTableBox->getRowSpan() < 1 )
1907  {
1908  // Store the row span offset:
1909  m_nRowSpanOffset = pTableBox->getRowSpan();
1910 
1911  // Move cursor to non-covered cell:
1912  const SwTableNode* pTableNd = pTableBoxStartNode->FindTableNode();
1913  pTableBox = & pTableBox->FindStartOfRowSpan( pTableNd->GetTable() );
1914  SwNodeIndex& rPtIdx = GetPoint()->nNode;
1915  SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
1916  rPtIdx = aNewIdx;
1917 
1918  GetDoc().GetNodes().GoNextSection( &rPtIdx, false, false );
1919  SwContentNode* pContentNode = GetContentNode();
1920  if ( pContentNode )
1921  {
1922  GetPoint()->nContent.Assign( pContentNode, bLeft ? pContentNode->Len() : 0 );
1923  }
1924  }
1925  }
1926  --nCnt;
1927  }
1928 
1929  // here come some special rules for visual cursor travelling
1930  if ( pSttFrame )
1931  {
1932  SwNode& rTmpNode = GetPoint()->nNode.GetNode();
1933  if ( &rTmpNode != &rNode && rTmpNode.IsTextNode() )
1934  {
1935  Point aPt;
1936  std::pair<Point, bool> const tmp(aPt, true);
1937  const SwContentFrame* pEndFrame = rTmpNode.GetTextNode()->getLayoutFrame(
1938  GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(),
1939  GetPoint(), &tmp);
1940  if ( pEndFrame )
1941  {
1942  if ( ! pEndFrame->IsRightToLeft() != ! pSttFrame->IsRightToLeft() )
1943  {
1944  if ( ! bLeft )
1945  pEndFrame->RightMargin( this );
1946  else
1947  pEndFrame->LeftMargin( this );
1948  }
1949  }
1950  }
1951  }
1952 
1953  return 0 == nCnt && !IsInProtectTable( true ) &&
1956 }
1957 
1958 // calculate cursor bidi level: extracted from UpDown()
1960 {
1961  SwNode& rNode = GetPoint()->nNode.GetNode();
1962  if ( !rNode.IsTextNode() )
1963  return;
1964 
1965  SwTextFrame const* pFrame;
1966  const SwScriptInfo* pSI =
1967  SwScriptInfo::GetScriptInfo( *rNode.GetTextNode(), &pFrame );
1968  if ( !pSI )
1969  return;
1970 
1971  SwIndex& rIdx = GetPoint()->nContent;
1972  const sal_Int32 nPos = rIdx.GetIndex();
1973 
1974  if (!(nPos && nPos < rNode.GetTextNode()->GetText().getLength()))
1975  return;
1976 
1977  TextFrameIndex const nIndex(pFrame->MapModelToView(rNode.GetTextNode(), nPos));
1978  const sal_uInt8 nCurrLevel = pSI->DirType( nIndex );
1979  const sal_uInt8 nPrevLevel = pSI->DirType( nIndex - TextFrameIndex(1) );
1980 
1981  if ( nCurrLevel % 2 != nPrevLevel % 2 )
1982  {
1983  // set cursor level to the lower of the two levels
1984  SetCursorBidiLevel( std::min( nCurrLevel, nPrevLevel ) );
1985  }
1986  else
1987  SetCursorBidiLevel( nCurrLevel );
1988 }
1989 
1990 bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
1991  Point const * pPt, tools::Long nUpDownX,
1992  SwRootFrame & rLayout)
1993 {
1994  SwTableCursor* pTableCursor = dynamic_cast<SwTableCursor*>(this);
1995  bool bAdjustTableCursor = false;
1996 
1997  // If the point/mark of the table cursor in the same box then set cursor to
1998  // beginning of the box
1999  if( pTableCursor && GetNode().StartOfSectionNode() ==
2000  GetNode( false ).StartOfSectionNode() )
2001  {
2002  if ( End() != GetPoint() )
2003  Exchange();
2004  bAdjustTableCursor = true;
2005  }
2006 
2007  bool bRet = false;
2008  Point aPt;
2009  if( pPt )
2010  aPt = *pPt;
2011  std::pair<Point, bool> const temp(aPt, true);
2012  SwContentFrame* pFrame = GetContentNode()->getLayoutFrame(&rLayout, GetPoint(), &temp);
2013 
2014  if( pFrame )
2015  {
2016  SwCursorSaveState aSave( *this );
2017 
2018  if( !pPt )
2019  {
2020  SwRect aTmpRect;
2021  pFrame->GetCharRect( aTmpRect, *GetPoint() );
2022  aPt = aTmpRect.Pos();
2023 
2024  nUpDownX = pFrame->IsVertical() ?
2025  aPt.getY() - pFrame->getFrameArea().Top() :
2026  aPt.getX() - pFrame->getFrameArea().Left();
2027  }
2028 
2029  // It is allowed to move footnotes in other footnotes but not sections
2030  const bool bChkRange = !pFrame->IsInFootnote() || HasMark();
2031  const SwPosition aOldPos( *GetPoint() );
2032  const bool bInReadOnly = IsReadOnlyAvailable();
2033 
2034  if ( bAdjustTableCursor && !bUp )
2035  {
2036  // Special case: We have a table cursor but the start box has more
2037  // than one paragraph. If we want to go down, we have to set the
2038  // point to the last frame in the table box. This is only necessary
2039  // if we do not already have a table selection
2040  const SwStartNode* pTableNd = GetNode().FindTableBoxStartNode();
2041  OSL_ENSURE( pTableNd, "pTableCursor without SwTableNode?" );
2042 
2043  if ( pTableNd ) // safety first
2044  {
2045  const SwNode* pEndNd = pTableNd->EndOfSectionNode();
2046  GetPoint()->nNode = *pEndNd;
2047  pTableCursor->Move( fnMoveBackward, GoInNode );
2048  std::pair<Point, bool> const tmp(aPt, true);
2049  pFrame = GetContentNode()->getLayoutFrame(&rLayout, GetPoint(), &tmp);
2050  }
2051  }
2052 
2053  while( nCnt &&
2054  (bUp ? pFrame->UnitUp( this, nUpDownX, bInReadOnly )
2055  : pFrame->UnitDown( this, nUpDownX, bInReadOnly ) ) &&
2056  CheckNodesRange( aOldPos.nNode, GetPoint()->nNode, bChkRange ))
2057  {
2058  std::pair<Point, bool> const tmp(aPt, true);
2059  pFrame = GetContentNode()->getLayoutFrame(&rLayout, GetPoint(), &tmp);
2060  --nCnt;
2061  }
2062 
2063  // iterate over whole number of items?
2064  if( !nCnt && !IsSelOvr( SwCursorSelOverFlags::Toggle |
2066  {
2067  if( !pTableCursor )
2068  {
2069  // try to position the cursor at half of the char-rect's height
2070  DisableCallbackAction a(rLayout);
2071  std::pair<Point, bool> const tmp(aPt, true);
2072  pFrame = GetContentNode()->getLayoutFrame(&rLayout, GetPoint(), &tmp);
2074  eTmpState.m_bSetInReadOnly = bInReadOnly;
2075  SwRect aTmpRect;
2076  pFrame->GetCharRect( aTmpRect, *GetPoint(), &eTmpState );
2077  if ( pFrame->IsVertical() )
2078  {
2079  aPt.setX(aTmpRect.Center().getX());
2080  pFrame->Calc(rLayout.GetCurrShell()->GetOut());
2081  aPt.setY(pFrame->getFrameArea().Top() + nUpDownX);
2082  }
2083  else
2084  {
2085  aPt.setY(aTmpRect.Center().getY());
2086  pFrame->Calc(rLayout.GetCurrShell()->GetOut());
2087  aPt.setX(pFrame->getFrameArea().Left() + nUpDownX);
2088  }
2089  pFrame->GetModelPositionForViewPoint( GetPoint(), aPt, &eTmpState );
2090  }
2092  }
2093  else
2094  {
2095  sal_Int32 nOffset = 0;
2096 
2097  // Jump to beginning or end of line when the cursor at first or last line.
2098  if(!bUp)
2099  {
2100  SwTextNode* pTextNd = GetPoint()->nNode.GetNode().GetTextNode();
2101  if (pTextNd)
2102  nOffset = pTextNd->GetText().getLength();
2103  }
2104  const SwPosition aPos(*GetContentNode(), nOffset);
2105 
2106  //if cursor has already been at start or end of file,
2107  //Update cursor to change nUpDownX.
2108  if ( aOldPos.nContent.GetIndex() == nOffset )
2109  {
2111  bRet = false;
2112  }
2113  else{
2114  *GetPoint() = aPos; // just give a new position
2115  bRet = true;
2116  }
2117 
2118  }
2119 
2120  DoSetBidiLevelUpDown(); // calculate cursor bidi level
2121  }
2122  return bRet;
2123 }
2124 
2125 bool SwCursor::LeftRightMargin(SwRootFrame const& rLayout, bool bLeft, bool bAPI)
2126 {
2127  Point aPt;
2128  std::pair<Point, bool> const tmp(aPt, true);
2129  SwContentFrame const*const pFrame = GetContentNode()->getLayoutFrame(
2130  &rLayout, GetPoint(), &tmp);
2131 
2132  // calculate cursor bidi level
2133  if ( pFrame )
2134  SetCursorBidiLevel( pFrame->IsRightToLeft() ? 1 : 0 );
2135 
2136  SwCursorSaveState aSave( *this );
2137  return pFrame
2138  && (bLeft ? pFrame->LeftMargin( this ) : pFrame->RightMargin( this, bAPI ) )
2140 }
2141 
2142 bool SwCursor::IsAtLeftRightMargin(SwRootFrame const& rLayout, bool bLeft, bool bAPI) const
2143 {
2144  bool bRet = false;
2145  Point aPt;
2146  std::pair<Point, bool> const tmp(aPt, true);
2147  SwContentFrame const*const pFrame = GetContentNode()->getLayoutFrame(
2148  &rLayout, GetPoint(), &tmp);
2149  if( pFrame )
2150  {
2151  SwPaM aPam( *GetPoint() );
2152  if( !bLeft && aPam.GetPoint()->nContent.GetIndex() )
2153  --aPam.GetPoint()->nContent;
2154  bRet = (bLeft ? pFrame->LeftMargin( &aPam )
2155  : pFrame->RightMargin( &aPam, bAPI ))
2156  && (!pFrame->IsTextFrame()
2157  || static_cast<SwTextFrame const*>(pFrame)->MapModelToViewPos(*aPam.GetPoint())
2158  == static_cast<SwTextFrame const*>(pFrame)->MapModelToViewPos(*GetPoint()));
2159  }
2160  return bRet;
2161 }
2162 
2163 bool SwCursor::SttEndDoc( bool bStt )
2164 {
2165  SwCursorSaveState aSave( *this );
2166  // Never jump over section boundaries during selection!
2167  // Can the cursor still moved on?
2168  SwMoveFnCollection const & fnMove = bStt ? fnMoveBackward : fnMoveForward;
2169  bool bRet = (!HasMark() || !IsNoContent() ) &&
2170  Move( fnMove, GoInDoc ) &&
2171  !IsInProtectTable( true ) &&
2175  return bRet;
2176 }
2177 
2178 bool SwCursor::GoPrevNextCell( bool bNext, sal_uInt16 nCnt )
2179 {
2180  const SwTableNode* pTableNd = GetPoint()->nNode.GetNode().FindTableNode();
2181  if( !pTableNd )
2182  return false;
2183 
2184  // If there is another EndNode in front of the cell's StartNode then there
2185  // exists a previous cell
2186  SwCursorSaveState aSave( *this );
2187  SwNodeIndex& rPtIdx = GetPoint()->nNode;
2188 
2189  while( nCnt-- )
2190  {
2191  const SwNode* pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode();
2192  const SwTableBox* pTableBox = pTableBoxStartNode->GetTableBox();
2193 
2194  // Check if we have to move the cursor to a covered cell before
2195  // proceeding:
2196  if (m_nRowSpanOffset)
2197  {
2198  if ( pTableBox && pTableBox->getRowSpan() > 1 )
2199  {
2200  pTableBox = & pTableBox->FindEndOfRowSpan( pTableNd->GetTable(),
2201  static_cast<sal_uInt16>(pTableBox->getRowSpan() + m_nRowSpanOffset));
2202  SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
2203  rPtIdx = aNewIdx;
2204  pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode();
2205  }
2206  m_nRowSpanOffset = 0;
2207  }
2208 
2209  const SwNode* pTmpNode = bNext ?
2210  pTableBoxStartNode->EndOfSectionNode() :
2211  pTableBoxStartNode;
2212 
2213  SwNodeIndex aCellIdx( *pTmpNode, bNext ? 1 : -1 );
2214  if( (bNext && !aCellIdx.GetNode().IsStartNode()) ||
2215  (!bNext && !aCellIdx.GetNode().IsEndNode()) )
2216  return false;
2217 
2218  if (bNext)
2219  rPtIdx = aCellIdx;
2220  else
2221  rPtIdx.Assign(*aCellIdx.GetNode().StartOfSectionNode());
2222 
2223  pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode();
2224  pTableBox = pTableBoxStartNode->GetTableBox();
2225  if ( pTableBox && pTableBox->getRowSpan() < 1 )
2226  {
2227  m_nRowSpanOffset = pTableBox->getRowSpan();
2228  // move cursor to non-covered cell:
2229  pTableBox = & pTableBox->FindStartOfRowSpan( pTableNd->GetTable() );
2230  SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
2231  rPtIdx = aNewIdx;
2232  }
2233  }
2234 
2235  ++rPtIdx;
2236  if( !rPtIdx.GetNode().IsContentNode() )
2237  GetDoc().GetNodes().GoNextSection( &rPtIdx, true, false );
2239 
2240  return !IsInProtectTable( true );
2241 }
2242 
2243 bool SwTableCursor::GotoTable( const OUString& )
2244 {
2245  return false; // invalid action
2246 }
2247 
2248 bool SwCursor::GotoTable( const OUString& rName )
2249 {
2250  bool bRet = false;
2251  if ( !HasMark() )
2252  {
2253  SwTable* pTmpTable = SwTable::FindTable( GetDoc().FindTableFormatByName( rName ) );
2254  if( pTmpTable )
2255  {
2256  // a table in a normal nodes array
2257  SwCursorSaveState aSave( *this );
2258  GetPoint()->nNode = *pTmpTable->GetTabSortBoxes()[ 0 ]->
2259  GetSttNd()->FindTableNode();
2261  bRet = !IsSelOvr();
2262  }
2263  }
2264  return bRet;
2265 }
2266 
2267 bool SwCursor::GotoTableBox( const OUString& rName )
2268 {
2269  bool bRet = false;
2270  const SwTableNode* pTableNd = GetPoint()->nNode.GetNode().FindTableNode();
2271  if( pTableNd )
2272  {
2273  // retrieve box by name
2274  const SwTableBox* pTableBox = pTableNd->GetTable().GetTableBox( rName );
2275  if( pTableBox && pTableBox->GetSttNd() &&
2276  ( !pTableBox->GetFrameFormat()->GetProtect().IsContentProtected() ||
2277  IsReadOnlyAvailable() ) )
2278  {
2279  SwCursorSaveState aSave( *this );
2280  GetPoint()->nNode = *pTableBox->GetSttNd();
2282  bRet = !IsSelOvr();
2283  }
2284  }
2285  return bRet;
2286 }
2287 
2288 bool SwCursor::MovePara(SwWhichPara fnWhichPara, SwMoveFnCollection const & fnPosPara )
2289 {
2290  // for optimization test something before
2291  const SwNode* pNd = &GetPoint()->nNode.GetNode();
2292  bool bShortCut = false;
2293  if ( fnWhichPara == GoCurrPara )
2294  {
2295  // #i41048#
2296  // If fnWhichPara == GoCurrPara then (*fnWhichPara)( *this, fnPosPara )
2297  // can already move the cursor to a different text node. In this case
2298  // we better check if IsSelOvr().
2299  const SwContentNode* pContentNd = pNd->GetContentNode();
2300  if ( pContentNd )
2301  {
2302  const sal_Int32 nSttEnd = &fnPosPara == &fnMoveForward ? 0 : pContentNd->Len();
2303  if ( GetPoint()->nContent.GetIndex() != nSttEnd )
2304  bShortCut = true;
2305  }
2306  }
2307  else
2308  {
2309  if ( pNd->IsTextNode() &&
2310  pNd->GetNodes()[ pNd->GetIndex() +
2311  (fnWhichPara == GoNextPara ? 1 : -1 ) ]->IsTextNode() )
2312  bShortCut = true;
2313  }
2314 
2315  if ( bShortCut )
2316  return (*fnWhichPara)( *this, fnPosPara );
2317 
2318  // else we must use the SaveStructure, because the next/prev is not
2319  // a same node type.
2320  SwCursorSaveState aSave( *this );
2321  return (*fnWhichPara)( *this, fnPosPara ) &&
2322  !IsInProtectTable( true ) &&
2325 }
2326 
2328  SwMoveFnCollection const & fnPosSect)
2329 {
2330  SwCursorSaveState aSave( *this );
2331  return (*fnWhichSect)( *this, fnPosSect ) &&
2332  !IsInProtectTable( true ) &&
2335 }
2336 
2338 {
2339  // This method is not supposed to be used in cases when nodes may be
2340  // deleted; detect such cases, but do not crash (example: fdo#40831).
2341  sal_uLong uNodeCount = GetPoint()->nNode.GetNodes().Count();
2342  OSL_ENSURE(m_vSavePos.empty() || m_vSavePos.back().nNode < uNodeCount,
2343  "SwCursor::RestoreSavePos: invalid node: "
2344  "probably something was deleted; consider using SwUnoCursor instead");
2345  if (m_vSavePos.empty() || m_vSavePos.back().nNode >= uNodeCount)
2346  return;
2347 
2348  GetPoint()->nNode = m_vSavePos.back().nNode;
2349 
2350  sal_Int32 nIdx = 0;
2351  if ( GetContentNode() )
2352  {
2353  if (m_vSavePos.back().nContent <= GetContentNode()->Len())
2354  nIdx = m_vSavePos.back().nContent;
2355  else
2356  {
2357  nIdx = GetContentNode()->Len();
2358  OSL_FAIL("SwCursor::RestoreSavePos: invalid content index");
2359  }
2360  }
2361  GetPoint()->nContent.Assign( GetContentNode(), nIdx );
2362 }
2363 
2365  : SwCursor( rPos, nullptr )
2366 {
2367  m_bParked = false;
2368  m_bChanged = false;
2369  m_nTablePtNd = 0;
2370  m_nTableMkNd = 0;
2371  m_nTablePtCnt = 0;
2372  m_nTableMkCnt = 0;
2373 }
2374 
2376 
2377 static bool
2378 lcl_SeekEntry(const SwSelBoxes& rTmp, SwStartNode const*const pSrch,
2379  size_t & o_rFndPos)
2380 {
2381  sal_uLong nIdx = pSrch->GetIndex();
2382 
2383  size_t nO = rTmp.size();
2384  if( nO > 0 )
2385  {
2386  nO--;
2387  size_t nU = 0;
2388  while( nU <= nO )
2389  {
2390  size_t nM = nU + ( nO - nU ) / 2;
2391  if( rTmp[ nM ]->GetSttNd() == pSrch )
2392  {
2393  o_rFndPos = nM;
2394  return true;
2395  }
2396  else if( rTmp[ nM ]->GetSttIdx() < nIdx )
2397  nU = nM + 1;
2398  else if( nM == 0 )
2399  return false;
2400  else
2401  nO = nM - 1;
2402  }
2403  }
2404  return false;
2405 }
2406 
2408 {
2409  if (m_bChanged)
2410  {
2411  if (m_bParked)
2412  {
2413  // move back into content
2414  Exchange();
2415  Move( fnMoveForward );
2416  Exchange();
2417  Move( fnMoveForward );
2418  m_bParked = false;
2419  }
2420 
2421  m_bChanged = false;
2422 
2423  // create temporary copies so that all boxes that
2424  // have already cursors can be removed
2426 
2427  // compare old and new ones
2428  SwNodes& rNds = pCurrentCursor->GetDoc().GetNodes();
2429  const SwStartNode* pSttNd;
2430  SwPaM* pCur = pCurrentCursor;
2431  do {
2432  size_t nPos;
2433  bool bDel = false;
2434  pSttNd = pCur->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
2435  if( !pCur->HasMark() || !pSttNd ||
2436  pSttNd != pCur->GetMark()->nNode.GetNode().FindTableBoxStartNode() )
2437  bDel = true;
2438 
2439  else if( lcl_SeekEntry( aTmp, pSttNd, nPos ))
2440  {
2441  SwNodeIndex aIdx( *pSttNd, 1 );
2442  const SwNode* pNd = &aIdx.GetNode();
2443  if( !pNd->IsContentNode() )
2444  pNd = rNds.GoNextSection( &aIdx, true, false );
2445 
2446  SwPosition* pPos = pCur->GetMark();
2447  if( pNd != &pPos->nNode.GetNode() )
2448  pPos->nNode = *pNd;
2449  pPos->nContent.Assign( const_cast<SwContentNode*>(static_cast<const SwContentNode*>(pNd)), 0 );
2450 
2451  aIdx.Assign( *pSttNd->EndOfSectionNode(), - 1 );
2452  pNd = &aIdx.GetNode();
2453  if( !pNd->IsContentNode() )
2454  pNd = SwNodes::GoPrevSection( &aIdx, true, false );
2455 
2456  pPos = pCur->GetPoint();
2457  if (pNd && pNd != &pPos->nNode.GetNode())
2458  pPos->nNode = *pNd;
2459  pPos->nContent.Assign(const_cast<SwContentNode*>(static_cast<const SwContentNode*>(pNd)), pNd ? static_cast<const SwContentNode*>(pNd)->Len() : 0);
2460 
2461  aTmp.erase( aTmp.begin() + nPos );
2462  }
2463  else
2464  bDel = true;
2465 
2466  pCur = pCur->GetNext();
2467  if( bDel )
2468  {
2469  SwPaM* pDel = pCur->GetPrev();
2470 
2471  if( pDel == pCurrentCursor )
2472  pCurrentCursor->DeleteMark();
2473  else
2474  delete pDel;
2475  }
2476  } while ( pCurrentCursor != pCur );
2477 
2478  for (size_t nPos = 0; nPos < aTmp.size(); ++nPos)
2479  {
2480  pSttNd = aTmp[ nPos ]->GetSttNd();
2481 
2482  SwNodeIndex aIdx( *pSttNd, 1 );
2483  if( &aIdx.GetNodes() != &rNds )
2484  break;
2485  SwNode* pNd = &aIdx.GetNode();
2486  if( !pNd->IsContentNode() )
2487  pNd = rNds.GoNextSection( &aIdx, true, false );
2488 
2489  SwPaM *const pNew = (!pCurrentCursor->IsMultiSelection() && !pCurrentCursor->HasMark())
2490  ? pCurrentCursor
2491  : pCurrentCursor->Create( pCurrentCursor );
2492  pNew->GetPoint()->nNode = *pNd;
2493  pNew->GetPoint()->nContent.Assign( static_cast<SwContentNode*>(pNd), 0 );
2494  pNew->SetMark();
2495 
2496  SwPosition* pPos = pNew->GetPoint();
2497  pPos->nNode.Assign( *pSttNd->EndOfSectionNode(), - 1 );
2498  pNd = &pPos->nNode.GetNode();
2499  if( !pNd->IsContentNode() )
2500  pNd = SwNodes::GoPrevSection( &pPos->nNode, true, false );
2501 
2502  pPos->nContent.Assign(static_cast<SwContentNode*>(pNd), pNd ? static_cast<SwContentNode*>(pNd)->Len() : 0);
2503  }
2504  }
2505  return pCurrentCursor;
2506 }
2507 
2508 void SwTableCursor::InsertBox( const SwTableBox& rTableBox )
2509 {
2510  SwTableBox* pBox = const_cast<SwTableBox*>(&rTableBox);
2511  m_SelectedBoxes.insert(pBox);
2512  m_bChanged = true;
2513 }
2514 
2515 void SwTableCursor::DeleteBox(size_t const nPos)
2516 {
2518  m_bChanged = true;
2519 }
2520 
2522 {
2523  bool bRet = false;
2524  const SwNode *pStart = GetNode().FindTableBoxStartNode();
2525  const SwNode *pEnd = GetNode(false).FindTableBoxStartNode();
2526  if( pStart && pEnd )
2527  {
2528  const SwTableNode *pTableNode = pStart->FindTableNode();
2529  if( pTableNode == pEnd->FindTableNode() &&
2530  pTableNode->GetTable().IsNewModel() )
2531  {
2532  bRet = true;
2534  pTableNode->GetTable().CreateSelection( pStart, pEnd, aNew,
2535  SwTable::SEARCH_NONE, false );
2536  ActualizeSelection( aNew );
2537  }
2538  }
2539  return bRet;
2540 }
2541 
2543 {
2544  size_t nOld = 0, nNew = 0;
2545  while (nOld < m_SelectedBoxes.size() && nNew < rNew.size())
2546  {
2547  SwTableBox const*const pPOld = m_SelectedBoxes[ nOld ];
2548  const SwTableBox* pPNew = rNew[ nNew ];
2549  if( pPOld == pPNew )
2550  { // this box will stay
2551  ++nOld;
2552  ++nNew;
2553  }
2554  else if( pPOld->GetSttIdx() < pPNew->GetSttIdx() )
2555  {
2556  DeleteBox( nOld ); // this box has to go
2557  }
2558  else
2559  {
2560  InsertBox( *pPNew ); // this is a new one
2561  ++nOld;
2562  ++nNew;
2563  }
2564  }
2565 
2566  while (nOld < m_SelectedBoxes.size())
2567  {
2568  DeleteBox( nOld ); // some more to delete
2569  }
2570 
2571  for ( ; nNew < rNew.size(); ++nNew ) // some more to insert
2572  {
2573  InsertBox( *rNew[ nNew ] );
2574  }
2575 }
2576 
2578 {
2579  if( !IsCursorMoved() )
2580  return false;
2581 
2586  return true;
2587 }
2588 
2591 {
2592  // de-register index from text node
2593  SwNode* pNd = &GetPoint()->nNode.GetNode();
2594  if( !pNd->IsStartNode() )
2595  pNd = pNd->StartOfSectionNode();
2596  GetPoint()->nNode = *pNd;
2597  GetPoint()->nContent.Assign( nullptr, 0 );
2598 
2599  pNd = &GetMark()->nNode.GetNode();
2600  if( !pNd->IsStartNode() )
2601  pNd = pNd->StartOfSectionNode();
2602  GetMark()->nNode = *pNd;
2603  GetMark()->nContent.Assign( nullptr, 0 );
2604 
2605  m_bChanged = true;
2606  m_bParked = true;
2607 }
2608 
2610 {
2611  bool bRet = false;
2612  for (size_t n = m_SelectedBoxes.size(); n; )
2613  {
2614  if (m_SelectedBoxes[--n]->GetFrameFormat()->GetProtect().IsContentProtected())
2615  {
2616  bRet = true;
2617  break;
2618  }
2619  }
2620  return bRet;
2621 }
2622 
2623 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool SttEndDoc(bool bSttDoc)
Definition: swcrsr.cxx:2163
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:983
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:686
Starts a section of nodes in the document model.
Definition: node.hxx:312
bool MovePara(SwWhichPara, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2288
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:157
virtual sal_Int32 Len() const
Definition: node.cxx:1245
static bool lcl_SeekEntry(const SwSelBoxes &rTmp, SwStartNode const *const pSrch, size_t &o_rFndPos)
Definition: swcrsr.cxx:2378
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:291
SAL_DLLPRIVATE void UpdateCursor(sal_uInt16 eFlags=SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, bool bIdleEnd=false)
Definition: crsrsh.cxx:1567
void InsertBox(const SwTableBox &rTableBox)
Definition: swcrsr.cxx:2508
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:970
SwTableCursor(const SwPosition &rPos)
Definition: swcrsr.cxx:2364
sal_uLong Count() const
Definition: ndarr.hxx:142
bool IsStartEndSentence(bool bEnd, SwRootFrame const *pLayout) const
Definition: swcrsr.cxx:1278
virtual ::sw::mark::IFieldmark * getFieldmarkAt(const SwPosition &rPos) const =0
get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
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:648
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:1328
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:754
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:210
virtual const SwRootFrame * GetCurrentLayout() const =0
sal_uLong GetSttIdx() const
Definition: swtable.cxx:1866
bool MoveSection(SwWhichSection, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2327
SwDocShell * GetDocShell()
Definition: doc.hxx:1353
bool GoCurrPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1016
virtual short MaxReplaceArived()
Definition: swcrsr.cxx:1141
bool IsAtLeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI) const
Definition: swcrsr.cxx:2142
void Left(const tools::Long nLeft)
Definition: swrect.hxx:195
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsInFootnote() const
Definition: frame.hxx:930
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:478
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:1212
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:187
static SwContentNode * GoPrevSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true)
Definition: nodes.cxx:1968
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:449
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:2370
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:56
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:1310
SwNode & GetNode() const
Definition: ndindex.hxx:119
SwCursor * MakeBoxSels(SwCursor *pCurrentCursor)
Definition: swcrsr.cxx:2407
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:1794
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:1788
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:1285
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:1731
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:1303
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
RET_CANCEL
bool IsReadOnlyUI() const
sal_uInt8 DirType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1684
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:170
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
sal_Int32 getRowSpan() const
Definition: swtable.cxx:75
SwDocPositions
Definition: cshtyp.hxx:103
const SwSection & GetSection() const
Definition: node.hxx:545
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:47
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:425
virtual bool IsSelOvrCheck(SwCursorSelOverFlags eFlags)
Definition: swcrsr.cxx:189
#define CH_TXTATR_INWORD
Definition: hintids.hxx:170
SwTableNode * GetTableNode()
Definition: node.hxx:603
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:178
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
Cursor Up/Down.
size_t pos
auto(*)(SwPaM &rPam, SwMoveFnCollection const &fnMove) -> bool SwGoInDoc
Definition: pam.hxx:126
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:41
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:2243
FindRanges
Definition: cshtyp.hxx:90
bool IsTextFrame() const
Definition: frame.hxx:1215
sal_Int32 GetStart() const
Definition: txatbase.hxx:86
virtual bool UnitUp(SwPaM *, const SwTwips nOffset, bool bSetInReadOnly) const
Definition: trvlfrm.cxx:966
virtual void DoUndo(bool const bDoUndo)=0
Enable/Disable Undo.
bool IsStartNode() const
Definition: node.hxx:628
bool IsCursorMovedUpdate()
Definition: swcrsr.cxx:2577
virtual void DoSetBidiLevelUpDown()
Definition: swcrsr.cxx:1959
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:259
const SwTable & GetTable() const
Definition: node.hxx:501
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:971
size_type size() const
virtual bool DoesUndo() const =0
Is Undo enabled?
virtual bool GotoTable(const OUString &rName)
Definition: swcrsr.cxx:2248
SwPaM * GetNext()
Definition: pam.hxx:264
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:72
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:261
bool IsContentNode() const
Definition: node.hxx:632
OUString GetText() const
Definition: pam.cxx:1076
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:504
static SwTable * FindTable(SwFrameFormat const *const pFormat)
Definition: swtable.cxx:1906
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:961
uno_Any a
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:132
SwDoc & GetDoc()
Definition: node.hxx:212
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:978
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:328
sw::FieldmarkMode GetFieldmarkMode() const
Definition: rootfrm.hxx:422
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:994
void Exchange()
Definition: pam.cxx:492
tools::Long m_nRowSpanOffset
Definition: swcrsr.hxx:75
bool IsHiddenFlag() const
Definition: section.hxx:187
SwContentNode * GetContentNode()
Definition: node.hxx:619
vector_type::size_type size_type
Definition: docary.hxx:228
void MakeStartIndex(SwIndex *pIdx)
Definition: node.hxx:400
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
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:178
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:1990
bool IsEndNode() const
Definition: node.hxx:636
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:697
bool GoInDoc(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:949
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:426
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:111
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:363
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:986
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:681
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
bool LeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI)
Definition: swcrsr.cxx:2125
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:2267
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:1219
SwNodes & GetNodes()
Definition: doc.hxx:408
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:968
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:3424
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:1044
bool GoPrevNextCell(bool bNext, sal_uInt16 nCnt)
Definition: swcrsr.cxx:2178
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1810
const sal_Int32 * End() const
Definition: txatbase.hxx:152
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:392
virtual ~SwTableCursor() override
Definition: swcrsr.cxx:2375
double getLength(const B2DPolygon &rCandidate)
bool IsAnFollow(const SwFlowFrame *pFlow) const
Definition: flowfrm.cxx:727
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:1045
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:180
void ParkCursor()
park table cursor on the boxes' start node
Definition: swcrsr.cxx:2590
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:197
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:357
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:954
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:1916
void ActualizeSelection(const SwSelBoxes &rBoxes)
Definition: swcrsr.cxx:2542
bool IsTableNode() const
Definition: node.hxx:644
const SvxProtectItem & GetProtect(bool=true) const
Definition: frmatr.hxx:82
SwDoc & GetDoc() const
Definition: pam.hxx:243
bool HasMergedParas() const
Definition: rootfrm.hxx:424
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:478
SectionType GetType() const
Definition: section.hxx:170
void DeleteBox(size_t nPos)
Definition: swcrsr.cxx:2515
SwSection * GetSection() const
Definition: section.cxx:674
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:187
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2067
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:208
SwSectionFormats & GetSections()
Definition: doc.hxx:1339
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:2521
CharClass & GetAppCharClass()
Definition: init.cxx:712
bool IsTextNode() const
Definition: node.hxx:640
bool HasReadOnlyBoxSel() const
Definition: swcrsr.cxx:2609
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:1293
void MakeEndIndex(SwIndex *pIdx)
Definition: node.hxx:401
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:2337
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:845
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:80
const SwCursor_SavePos * GetSavePos() const
Definition: swcrsr.hxx:87