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