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