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