LibreOffice Module sw (master)  1
pam.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 <sal/config.h>
21 
22 #include <string_view>
23 
24 #include <tools/gen.hxx>
25 #include <editeng/protitem.hxx>
26 #include <cntfrm.hxx>
27 #include <pagefrm.hxx>
28 #include <doc.hxx>
30 #include <docary.hxx>
31 #include <pam.hxx>
32 #include <pamtyp.hxx>
33 #include <txtfrm.hxx>
34 #include <fmtcntnt.hxx>
35 #include <frmatr.hxx>
36 #include <flyfrm.hxx>
37 #include <fmteiro.hxx>
38 #include <section.hxx>
39 #include <sectfrm.hxx>
40 #include <ndtxt.hxx>
41 #include <swcrsr.hxx>
42 
43 #include <IMark.hxx>
45 #include <hints.hxx>
46 #include <txatbase.hxx>
47 #include <osl/diagnose.h>
48 #include <xmloff/odffields.hxx>
49 #include <rtl/ustrbuf.hxx>
50 
51 #include <editsh.hxx>
52 
53 // for the dump "MSC-" compiler
54 static sal_Int32 GetSttOrEnd( bool bCondition, const SwContentNode& rNd )
55 {
56  return bCondition ? 0 : rNd.Len();
57 }
58 
59 SwPosition::SwPosition( const SwNodeIndex & rNodeIndex, const SwIndex & rContent )
60  : nNode( rNodeIndex ), nContent( rContent )
61 {
62 }
63 
64 SwPosition::SwPosition( const SwNodeIndex & rNodeIndex )
65  : nNode( rNodeIndex ), nContent( nNode.GetNode().GetContentNode() )
66 {
67 }
68 
70  : nNode( rNode ), nContent( nNode.GetNode().GetContentNode() )
71 {
72 }
73 
74 SwPosition::SwPosition( SwContentNode & rNode, const sal_Int32 nOffset )
75  : nNode( rNode ), nContent( &rNode, nOffset )
76 {
77 }
78 
79 bool SwPosition::operator<(const SwPosition &rPos) const
80 {
81  if( nNode < rPos.nNode )
82  return true;
83  if( nNode == rPos.nNode )
84  {
85  // note that positions with text node but no SwIndex registered are
86  // created for text frames anchored at para (see SwXFrame::getAnchor())
87  SwIndexReg const*const pThisReg(nContent.GetIdxReg());
88  SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
89  if (pThisReg && pOtherReg)
90  {
91  return (nContent < rPos.nContent);
92  }
93  else // by convention position with no index is smaller
94  {
95  return pOtherReg != nullptr;
96  }
97  }
98  return false;
99 }
100 
101 bool SwPosition::operator>(const SwPosition &rPos) const
102 {
103  if(nNode > rPos.nNode )
104  return true;
105  if( nNode == rPos.nNode )
106  {
107  // note that positions with text node but no SwIndex registered are
108  // created for text frames anchored at para (see SwXFrame::getAnchor())
109  SwIndexReg const*const pThisReg(nContent.GetIdxReg());
110  SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
111  if (pThisReg && pOtherReg)
112  {
113  return (nContent > rPos.nContent);
114  }
115  else // by convention position with no index is smaller
116  {
117  return pThisReg != nullptr;
118  }
119  }
120  return false;
121 }
122 
123 bool SwPosition::operator<=(const SwPosition &rPos) const
124 {
125  if(nNode < rPos.nNode )
126  return true;
127  if( nNode == rPos.nNode )
128  {
129  // note that positions with text node but no SwIndex registered are
130  // created for text frames anchored at para (see SwXFrame::getAnchor())
131  SwIndexReg const*const pThisReg(nContent.GetIdxReg());
132  SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
133  if (pThisReg && pOtherReg)
134  {
135  return (nContent <= rPos.nContent);
136  }
137  else // by convention position with no index is smaller
138  {
139  return pThisReg == nullptr;
140  }
141  }
142  return false;
143 }
144 
145 bool SwPosition::operator>=(const SwPosition &rPos) const
146 {
147  if(nNode > rPos.nNode )
148  return true;
149  if( nNode == rPos.nNode )
150  {
151  // note that positions with text node but no SwIndex registered are
152  // created for text frames anchored at para (see SwXFrame::getAnchor())
153  SwIndexReg const*const pThisReg(nContent.GetIdxReg());
154  SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
155  if (pThisReg && pOtherReg)
156  {
157  return (nContent >= rPos.nContent);
158  }
159  else // by convention position with no index is smaller
160  {
161  return pOtherReg == nullptr;
162  }
163  }
164  return false;
165 }
166 
167 bool SwPosition::operator==(const SwPosition &rPos) const
168 {
169  return (nNode == rPos.nNode)
170  && (nContent == rPos.nContent);
171 }
172 
173 bool SwPosition::operator!=(const SwPosition &rPos) const
174 {
175  return (nNode != rPos.nNode)
176  || (nContent != rPos.nContent);
177 }
178 
180 {
181  return nNode.GetNode().GetDoc();
182 }
183 
185 {
186  xmlTextWriterStartElement(pWriter, BAD_CAST("SwPosition"));
187  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nNode"), BAD_CAST(OString::number(nNode.GetIndex()).getStr()));
188  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nContent"), BAD_CAST(OString::number(nContent.GetIndex()).getStr()));
189  xmlTextWriterEndElement(pWriter);
190 }
191 
192 std::ostream &operator <<(std::ostream& s, const SwPosition& position)
193 {
194  return s << "SwPosition (node " << position.nNode.GetIndex() << ", offset " << position.nContent.GetIndex() << ")";
195 }
196 
197 namespace {
198 
199 enum CHKSECTION { Chk_Both, Chk_One, Chk_None };
200 
201 }
202 
203 static CHKSECTION lcl_TstIdx( sal_uLong nSttIdx, sal_uLong nEndIdx, const SwNode& rEndNd )
204 {
205  sal_uLong nStt = rEndNd.StartOfSectionIndex(), nEnd = rEndNd.GetIndex();
206  CHKSECTION eSec = nStt < nSttIdx && nEnd >= nSttIdx ? Chk_One : Chk_None;
207  if( nStt < nEndIdx && nEnd >= nEndIdx )
208  return( eSec == Chk_One ? Chk_Both : Chk_One );
209  return eSec;
210 }
211 
212 static bool lcl_ChkOneRange( CHKSECTION eSec, bool bChkSections,
213  const SwNode& rBaseEnd, sal_uLong nStt, sal_uLong nEnd )
214 {
215  if( eSec != Chk_Both )
216  return false;
217 
218  if( !bChkSections )
219  return true;
220 
221  // search the surrounding section
222  const SwNodes& rNds = rBaseEnd.GetNodes();
223  const SwNode *pTmp, *pNd = rNds[ nStt ];
224  if( !pNd->IsStartNode() )
225  pNd = pNd->StartOfSectionNode();
226 
227  if( pNd == rNds[ nEnd ]->StartOfSectionNode() )
228  return true; // same StartNode, same section
229 
230  // already on a base node => error
231  if( !pNd->StartOfSectionIndex() )
232  return false;
233 
234  for (;;)
235  {
236  pTmp = pNd->StartOfSectionNode();
237  if (pTmp->EndOfSectionNode() == &rBaseEnd )
238  break;
239  pNd = pTmp;
240  }
241 
242  sal_uLong nSttIdx = pNd->GetIndex(), nEndIdx = pNd->EndOfSectionIndex();
243  return nSttIdx <= nStt && nStt <= nEndIdx &&
244  nSttIdx <= nEnd && nEnd <= nEndIdx;
245 }
246 
257 bool CheckNodesRange( const SwNodeIndex& rStt,
258  const SwNodeIndex& rEnd, bool bChkSection )
259 {
260  const SwNodes& rNds = rStt.GetNodes();
261  sal_uLong nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
262  CHKSECTION eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfContent() );
263  if( Chk_None != eSec )
264  return eSec == Chk_Both;
265 
266  eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfAutotext() );
267  if( Chk_None != eSec )
268  return lcl_ChkOneRange( eSec, bChkSection,
269  rNds.GetEndOfAutotext(), nStt, nEnd );
270 
271  eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfPostIts() );
272  if( Chk_None != eSec )
273  return lcl_ChkOneRange( eSec, bChkSection,
274  rNds.GetEndOfPostIts(), nStt, nEnd );
275 
276  eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfInserts() );
277  if( Chk_None != eSec )
278  return lcl_ChkOneRange( eSec, bChkSection,
279  rNds.GetEndOfInserts(), nStt, nEnd );
280 
281  eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfRedlines() );
282  if( Chk_None != eSec )
283  return lcl_ChkOneRange( eSec, bChkSection,
284  rNds.GetEndOfRedlines(), nStt, nEnd );
285 
286  return false; // somewhere in between => error
287 }
288 
289 bool GoNext(SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
290 {
291  if( pNd->IsContentNode() )
292  return static_cast<SwContentNode*>(pNd)->GoNext( pIdx, nMode );
293  return false;
294 }
295 
296 bool GoPrevious( SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
297 {
298  if( pNd->IsContentNode() )
299  return static_cast<SwContentNode*>(pNd)->GoPrevious( pIdx, nMode );
300  return false;
301 }
302 
303 SwContentNode* GoNextNds( SwNodeIndex* pIdx, bool bChk )
304 {
305  SwNodeIndex aIdx( *pIdx );
306  SwContentNode* pNd = aIdx.GetNodes().GoNext( &aIdx );
307  if( pNd )
308  {
309  if( bChk && 1 != aIdx.GetIndex() - pIdx->GetIndex() &&
310  !CheckNodesRange( *pIdx, aIdx, true ) )
311  pNd = nullptr;
312  else
313  *pIdx = aIdx;
314  }
315  return pNd;
316 }
317 
319 {
320  SwNodeIndex aIdx( *pIdx );
321  SwContentNode* pNd = SwNodes::GoPrevious( &aIdx );
322  if( pNd )
323  {
324  if( bChk && 1 != pIdx->GetIndex() - aIdx.GetIndex() &&
325  !CheckNodesRange( *pIdx, aIdx, true ) )
326  pNd = nullptr;
327  else
328  *pIdx = aIdx;
329  }
330  return pNd;
331 }
332 
333 SwPaM::SwPaM( const SwPosition& rPos, SwPaM* pRing )
334  : Ring( pRing )
335  , m_Bound1( rPos )
336  , m_Bound2( rPos.nNode.GetNode().GetNodes() ) // default initialize
337  , m_pPoint( &m_Bound1 )
338  , m_pMark( m_pPoint )
339  , m_bIsInFrontOfLabel( false )
340 {
341 }
342 
343 SwPaM::SwPaM( const SwPosition& rMark, const SwPosition& rPoint, SwPaM* pRing )
344  : Ring( pRing )
345  , m_Bound1( rMark )
346  , m_Bound2( rPoint )
347  , m_pPoint( &m_Bound2 )
348  , m_pMark( &m_Bound1 )
349  , m_bIsInFrontOfLabel( false )
350 {
351 }
352 
353 SwPaM::SwPaM( const SwNodeIndex& rMark, const SwNodeIndex& rPoint,
354  tools::Long nMarkOffset, tools::Long nPointOffset, SwPaM* pRing )
355  : Ring( pRing )
356  , m_Bound1( rMark )
357  , m_Bound2( rPoint )
358  , m_pPoint( &m_Bound2 )
359  , m_pMark( &m_Bound1 )
360  , m_bIsInFrontOfLabel( false )
361 {
362  if ( nMarkOffset )
363  {
364  m_pMark->nNode += nMarkOffset;
365  }
366  if ( nPointOffset )
367  {
368  m_pPoint->nNode += nPointOffset;
369  }
372 }
373 
374 SwPaM::SwPaM( const SwNode& rMark, const SwNode& rPoint,
375  tools::Long nMarkOffset, tools::Long nPointOffset, SwPaM* pRing )
376  : Ring( pRing )
377  , m_Bound1( rMark )
378  , m_Bound2( rPoint )
379  , m_pPoint( &m_Bound2 )
380  , m_pMark( &m_Bound1 )
381  , m_bIsInFrontOfLabel( false )
382 {
383  if ( nMarkOffset )
384  {
385  m_pMark->nNode += nMarkOffset;
386  }
387  if ( nPointOffset )
388  {
389  m_pPoint->nNode += nPointOffset;
390  }
393 }
394 
395 SwPaM::SwPaM( const SwNodeIndex& rMark, sal_Int32 nMarkContent,
396  const SwNodeIndex& rPoint, sal_Int32 nPointContent, SwPaM* pRing )
397  : Ring( pRing )
398  , m_Bound1( rMark )
399  , m_Bound2( rPoint )
400  , m_pPoint( &m_Bound2 )
401  , m_pMark( &m_Bound1 )
402  , m_bIsInFrontOfLabel( false )
403 {
404  m_pPoint->nContent.Assign( rPoint.GetNode().GetContentNode(), nPointContent);
405  m_pMark ->nContent.Assign( rMark .GetNode().GetContentNode(), nMarkContent );
406 }
407 
408 SwPaM::SwPaM( const SwNode& rMark, sal_Int32 nMarkContent,
409  const SwNode& rPoint, sal_Int32 nPointContent, SwPaM* pRing )
410  : Ring( pRing )
411  , m_Bound1( rMark )
412  , m_Bound2( rPoint )
413  , m_pPoint( &m_Bound2 )
414  , m_pMark( &m_Bound1 )
415  , m_bIsInFrontOfLabel( false )
416 {
418  nPointContent);
419  m_pMark ->nContent.Assign( m_pMark ->nNode.GetNode().GetContentNode(),
420  nMarkContent );
421 }
422 
423 SwPaM::SwPaM( const SwNode& rNode, sal_Int32 nContent, SwPaM* pRing )
424  : Ring( pRing )
425  , m_Bound1( rNode )
426  , m_Bound2( m_Bound1.nNode.GetNode().GetNodes() ) // default initialize
427  , m_pPoint( &m_Bound1 )
428  , m_pMark( &m_Bound1 )
429  , m_bIsInFrontOfLabel( false )
430 {
432  nContent );
433 }
434 
435 SwPaM::SwPaM( const SwNodeIndex& rNodeIdx, sal_Int32 nContent, SwPaM* pRing )
436  : Ring( pRing )
437  , m_Bound1( rNodeIdx )
438  , m_Bound2( rNodeIdx.GetNode().GetNodes() ) // default initialize
439  , m_pPoint( &m_Bound1 )
440  , m_pMark( &m_Bound1 )
441  , m_bIsInFrontOfLabel( false )
442 {
443  m_pPoint->nContent.Assign( rNodeIdx.GetNode().GetContentNode(), nContent );
444 }
445 
447 
448 SwPaM::SwPaM(SwPaM const& rPam, SwPaM *const pRing)
449  : Ring(pRing)
450  , m_Bound1( *(rPam.m_pPoint) )
451  , m_Bound2( *(rPam.m_pMark) )
452  , m_pPoint( &m_Bound1 ), m_pMark( rPam.HasMark() ? &m_Bound2 : m_pPoint )
453  , m_bIsInFrontOfLabel( false )
454 {
455 }
456 
457 // @@@ semantic: no copy assignment for super class Ring.
458 SwPaM &SwPaM::operator=( const SwPaM &rPam )
459 {
460  if(this == &rPam)
461  return *this;
462 
463  *m_pPoint = *( rPam.m_pPoint );
464  if ( rPam.HasMark() )
465  {
466  SetMark();
467  *m_pMark = *( rPam.m_pMark );
468  }
469  else
470  {
471  DeleteMark();
472  }
473  return *this;
474 }
475 
477 {
478  if (m_pPoint == &m_Bound1)
479  {
480  m_pMark = &m_Bound2;
481  }
482  else
483  {
484  m_pMark = &m_Bound1;
485  }
486  (*m_pMark) = *m_pPoint;
487 }
488 
489 #ifdef DBG_UTIL
491 {
492  if (m_pPoint != m_pMark)
493  {
494  SwPosition *pTmp = m_pPoint;
495  m_pPoint = m_pMark;
496  m_pMark = pTmp;
497  }
498 }
499 #endif
500 
502 bool SwPaM::Move( SwMoveFnCollection const & fnMove, SwGoInDoc fnGo )
503 {
504  const bool bRet = (*fnGo)( *this, fnMove );
505 
506  m_bIsInFrontOfLabel = false;
507  return bRet;
508 }
509 
510 namespace sw {
511 
522 std::unique_ptr<SwPaM> MakeRegion(SwMoveFnCollection const & fnMove,
523  const SwPaM & rOrigRg)
524 {
525  std::unique_ptr<SwPaM> pPam;
526  {
527  pPam.reset(new SwPaM(rOrigRg, const_cast<SwPaM*>(&rOrigRg))); // given search range
528  // make sure that SPoint is on the "real" start position
529  // FORWARD: SPoint always smaller than GetMark
530  // BACKWARD: SPoint always bigger than GetMark
531  if( (pPam->GetMark()->*fnMove.fnCmpOp)( *pPam->GetPoint() ) )
532  pPam->Exchange();
533  }
534  return pPam;
535 }
536 
537 } // namespace sw
538 
539 void SwPaM::Normalize(bool bPointFirst)
540 {
541  if (HasMark())
542  if ( ( bPointFirst && *m_pPoint > *m_pMark) ||
543  (!bPointFirst && *m_pPoint < *m_pMark) )
544  {
545  Exchange();
546  }
547 }
548 
550 sal_uInt16 SwPaM::GetPageNum( bool bAtPoint, const Point* pLayPos )
551 {
552  const SwContentFrame* pCFrame;
553  const SwPageFrame *pPg;
554  const SwContentNode *pNd ;
555  const SwPosition* pPos = bAtPoint ? m_pPoint : m_pMark;
556 
557  std::pair<Point, bool> tmp;
558  if (pLayPos)
559  {
560  tmp.first = *pLayPos;
561  tmp.second = false;
562  }
563  if( nullptr != ( pNd = pPos->nNode.GetNode().GetContentNode() ) &&
564  nullptr != (pCFrame = pNd->getLayoutFrame(pNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), pPos, pLayPos ? &tmp : nullptr)) &&
565  nullptr != ( pPg = pCFrame->FindPageFrame() ))
566  return pPg->GetPhyPageNum();
567  return 0;
568 }
569 
570 // form view - see also SwCursorShell::IsCursorReadonly()
571 static const SwFrame* lcl_FindEditInReadonlyFrame( const SwFrame& rFrame )
572 {
573  const SwFrame* pRet = nullptr;
574 
575  const SwFlyFrame* pFly;
576  const SwSectionFrame* pSectionFrame;
577 
578  if( rFrame.IsInFly() &&
579  (pFly = rFrame.FindFlyFrame())->GetFormat()->GetEditInReadonly().GetValue() &&
580  pFly->Lower() &&
581  !pFly->Lower()->IsNoTextFrame() )
582  {
583  pRet = pFly;
584  }
585  else if ( rFrame.IsInSct() &&
586  nullptr != ( pSectionFrame = rFrame.FindSctFrame() )->GetSection() &&
587  pSectionFrame->GetSection()->IsEditInReadonlyFlag() )
588  {
589  pRet = pSectionFrame;
590  }
591 
592  return pRet;
593 }
594 
596 bool SwPaM::HasReadonlySel( bool bFormView ) const
597 {
598  bool bRet = false;
599 
600  const SwContentNode* pNd = GetPoint()->nNode.GetNode().GetContentNode();
601  const SwContentFrame *pFrame = nullptr;
602  if ( pNd != nullptr )
603  {
604  Point aTmpPt;
605  std::pair<Point, bool> const tmp(aTmpPt, false);
606  pFrame = pNd->getLayoutFrame(
608  GetPoint(), &tmp);
609  }
610 
611  // Will be set if point are inside edit-in-readonly environment
612  const SwFrame* pPointEditInReadonlyFrame = nullptr;
613  if ( pFrame != nullptr
614  && ( pFrame->IsProtected()
615  || ( bFormView
616  && nullptr == ( pPointEditInReadonlyFrame = lcl_FindEditInReadonlyFrame( *pFrame ) ) ) ) )
617  {
618  bRet = true;
619  }
620  else if( pNd != nullptr )
621  {
622  const SwSectionNode* pSNd = pNd->GetSectionNode();
623  if ( pSNd != nullptr
624  && ( pSNd->GetSection().IsProtectFlag()
625  || ( bFormView
626  && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
627  {
628  bRet = true;
629  }
630  else
631  {
632  const SwSectionNode* pParentSectionNd = pNd->FindSectionNode();
633  if ( pParentSectionNd != nullptr
634  && ( pParentSectionNd->GetSection().IsProtectFlag()
635  || ( bFormView && !pParentSectionNd->GetSection().IsEditInReadonlyFlag()) ) )
636  {
637  bRet = true;
638  }
639  }
640  }
641 
642  if ( !bRet
643  && HasMark()
644  && GetPoint()->nNode != GetMark()->nNode )
645  {
646  pNd = GetMark()->nNode.GetNode().GetContentNode();
647  pFrame = nullptr;
648  if ( pNd != nullptr )
649  {
650  Point aTmpPt;
651  std::pair<Point, bool> const tmp(aTmpPt, false);
652  pFrame = pNd->getLayoutFrame(
654  GetMark(), &tmp);
655  }
656 
657  const SwFrame* pMarkEditInReadonlyFrame = nullptr;
658  if ( pFrame != nullptr
659  && ( pFrame->IsProtected()
660  || ( bFormView
661  && nullptr == ( pMarkEditInReadonlyFrame = lcl_FindEditInReadonlyFrame( *pFrame ) ) ) ) )
662  {
663  bRet = true;
664  }
665  else if( pNd != nullptr )
666  {
667  const SwSectionNode* pSNd = pNd->GetSectionNode();
668  if ( pSNd != nullptr
669  && ( pSNd->GetSection().IsProtectFlag()
670  || ( bFormView
671  && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
672  {
673  bRet = true;
674  }
675  }
676 
677  if ( !bRet && bFormView )
678  {
679  // Check if start and end frame are inside the _same_
680  // edit-in-readonly-environment. Otherwise we better return 'true'
681  if ( pPointEditInReadonlyFrame != pMarkEditInReadonlyFrame )
682  bRet = true;
683  }
684 
685  // check for protected section inside the selection
686  if( !bRet )
687  {
688  sal_uLong nSttIdx = GetMark()->nNode.GetIndex(),
689  nEndIdx = GetPoint()->nNode.GetIndex();
690  if( nEndIdx <= nSttIdx )
691  {
692  sal_uLong nTmp = nSttIdx;
693  nSttIdx = nEndIdx;
694  nEndIdx = nTmp;
695  }
696 
697  // If a protected section should be between nodes, then the
698  // selection needs to contain already x nodes.
699  // (TextNd, SectNd, TextNd, EndNd, TextNd )
700  if( nSttIdx + 3 < nEndIdx )
701  {
702  const SwSectionFormats& rFormats = GetDoc().GetSections();
703  for( SwSectionFormats::size_type n = rFormats.size(); n; )
704  {
705  const SwSectionFormat* pFormat = rFormats[ --n ];
706  if( pFormat->GetProtect().IsContentProtected() )
707  {
708  const SwFormatContent& rContent = pFormat->GetContent(false);
709  OSL_ENSURE( rContent.GetContentIdx(), "where is the SectionNode?" );
710  sal_uLong nIdx = rContent.GetContentIdx()->GetIndex();
711  if( nSttIdx <= nIdx && nEndIdx >= nIdx &&
712  rContent.GetContentIdx()->GetNode().GetNodes().IsDocNodes() )
713  {
714  bRet = true;
715  break;
716  }
717  }
718  }
719  }
720  }
721  }
722 
723  const SwDoc& rDoc = GetDoc();
724  // Legacy text/combo/checkbox: never return read-only when inside these form fields.
725  const IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess();
726  sw::mark::IFieldmark* pA = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : nullptr;
727  sw::mark::IFieldmark* pB = GetMark() ? pMarksAccess->getFieldmarkFor( *GetMark( ) ) : pA;
728  // prevent the user from accidentally deleting the field itself when modifying the text.
729  const bool bAtStartA = (pA != nullptr) && (pA->GetMarkStart() == *GetPoint());
730  const bool bAtStartB = (pB != nullptr) && (pB->GetMarkStart() == *GetMark());
731 
732  if (!bRet)
733  {
734  bool bUnhandledMark = pA && pA->GetFieldname( ) == ODF_UNHANDLED;
735  // Unhandled fieldmarks case shouldn't be edited manually to avoid breaking anything
736  if ( ( pA == pB ) && bUnhandledMark )
737  bRet = true;
738  else
739  {
740  if ((pA == pB) && (bAtStartA != bAtStartB))
741  bRet = true;
742  else if (pA != pB)
743  {
744  // If both points are either outside or at marks edges (i.e. selection either
745  // touches fields, or fully encloses it), then don't disable editing
746  bRet = !( ( !pA || bAtStartA ) && ( !pB || bAtStartB ) );
747  }
748  if( !bRet && rDoc.GetDocumentSettingManager().get( DocumentSettingId::PROTECT_FORM ) && (pA || pB) )
749  {
750  // Form protection case
751  bRet = ( pA == nullptr ) || ( pB == nullptr ) || bAtStartA || bAtStartB;
752  }
753  }
754  }
755  else
756  {
757  // Allow editing when the cursor/selection is fully inside of a legacy form field.
758  bRet = !( pA != nullptr && !bAtStartA && !bAtStartB && pA == pB );
759  }
760 
761  if (!bRet)
762  {
763  // Paragraph Signatures and Classification fields are read-only.
764  if (rDoc.GetEditShell())
766  }
767 
768  if (!bRet &&
770  {
771  if (rDoc.getIDocumentMarkAccess()->isBookmarkDeleted(*this))
772  {
773  return true;
774  }
775  }
776  if (!bRet &&
778  {
779  SwPosition const& rStart(*Start());
780  SwPosition const& rEnd(*End());
781  for (SwNodeIndex n = rStart.nNode; n <= rEnd.nNode; ++n)
782  {
783  if (SwTextNode const*const pNode = n.GetNode().GetTextNode())
784  {
785  if (SwpHints const*const pHints = pNode->GetpSwpHints())
786  {
787  for (size_t i = 0; i < pHints->Count(); ++i)
788  {
789  SwTextAttr const*const pHint(pHints->Get(i));
790  if (n == rStart.nNode && pHint->GetStart() < rStart.nContent.GetIndex())
791  {
792  continue; // before selection
793  }
794  if (n == rEnd.nNode && rEnd.nContent.GetIndex() <= pHint->GetStart())
795  {
796  break; // after selection
797  }
798  if (pHint->Which() == RES_TXTATR_FIELD
799  // placeholders don't work if you can't delete them
800  && pHint->GetFormatField().GetField()->GetTyp()->Which() != SwFieldIds::JumpEdit)
801  {
802  return true;
803  }
804  }
805  }
806  }
807  }
808  }
809 
810  return bRet;
811 }
812 
817 SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFnCollection const & fnMove,
818  bool const bInReadOnly, SwRootFrame const*const i_pLayout)
819 {
820  SwRootFrame const*const pLayout(i_pLayout ? i_pLayout :
822  SwContentNode * pNd = nullptr;
823  if( ((*rPam.GetPoint()).*fnMove.fnCmpOp)( *rPam.GetMark() ) ||
824  ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) )
825  {
826  if( rbFirst )
827  {
828  rbFirst = false;
829  pNd = rPam.GetContentNode();
830  if( pNd )
831  {
832  SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout));
833  if(
834  (
835  nullptr == pFrame ||
836  ( !bInReadOnly && pFrame->IsProtected() ) ||
837  (pFrame->IsTextFrame() && static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow())
838  ) ||
839  ( !bInReadOnly && pNd->FindSectionNode() &&
840  pNd->FindSectionNode()->GetSection().IsProtect()
841  )
842  )
843  {
844  pNd = nullptr;
845  }
846  }
847  }
848 
849  if( !pNd ) // is the cursor not on a ContentNode?
850  {
851  SwPosition aPos( *rPam.GetPoint() );
852  bool bSrchForward = &fnMove == &fnMoveForward;
853  SwNodes& rNodes = aPos.nNode.GetNodes();
854 
855  // go to next/previous ContentNode
856  while( true )
857  {
858  if (i_pLayout && aPos.nNode.GetNode().IsTextNode())
859  {
860  auto const fal(sw::GetFirstAndLastNode(*pLayout, aPos.nNode));
861  aPos.nNode = bSrchForward ? *fal.second : *fal.first;
862  }
863 
864  pNd = bSrchForward
865  ? rNodes.GoNextSection( &aPos.nNode, true, !bInReadOnly )
866  : SwNodes::GoPrevSection( &aPos.nNode, true, !bInReadOnly );
867  if( pNd )
868  {
869  aPos.nContent.Assign( pNd, ::GetSttOrEnd( bSrchForward,*pNd ));
870  // is the position still in the area
871  if( (aPos.*fnMove.fnCmpOp)( *rPam.GetMark() ) )
872  {
873  // only in AutoTextSection can be nodes that are hidden
874  SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout));
875  if (nullptr == pFrame ||
876  ( !bInReadOnly && pFrame->IsProtected() ) ||
877  ( pFrame->IsTextFrame() &&
878  static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()))
879  {
880  pNd = nullptr;
881  continue;
882  }
883  *rPam.GetPoint() = aPos;
884  }
885  else
886  pNd = nullptr; // no valid node
887  break;
888  }
889  break;
890  }
891  }
892  }
893  return pNd;
894 }
895 
896 void GoStartDoc( SwPosition * pPos )
897 {
898  SwNodes& rNodes = pPos->nNode.GetNodes();
899  pPos->nNode = *rNodes.GetEndOfContent().StartOfSectionNode();
900  // we always need to find a ContentNode!
901  SwContentNode* pCNd = rNodes.GoNext( &pPos->nNode );
902  if( pCNd )
903  pCNd->MakeStartIndex( &pPos->nContent );
904 }
905 
906 void GoEndDoc( SwPosition * pPos )
907 {
908  SwNodes& rNodes = pPos->nNode.GetNodes();
909  pPos->nNode = rNodes.GetEndOfContent();
910  SwContentNode* pCNd = GoPreviousNds( &pPos->nNode, true );
911  if( pCNd )
912  pCNd->MakeEndIndex( &pPos->nContent );
913 }
914 
916 {
917  // jump to section's beginning
918  SwNodes& rNodes = pPos->nNode.GetNodes();
919  sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->nNode );
920  if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
921  nLevel--;
922  do { SwNodes::GoStartOfSection( &pPos->nNode ); } while( nLevel-- );
923 
924  // already on a ContentNode
925  pPos->nNode.GetNode().GetContentNode()->MakeStartIndex( &pPos->nContent );
926 }
927 
929 void GoEndSection( SwPosition * pPos )
930 {
931  // jump to section's beginning/end
932  SwNodes& rNodes = pPos->nNode.GetNodes();
933  sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->nNode );
934  if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
935  nLevel--;
936  do { SwNodes::GoEndOfSection( &pPos->nNode ); } while( nLevel-- );
937 
938  // now on an EndNode, thus to the previous ContentNode
939  if( GoPreviousNds( &pPos->nNode, true ) )
940  pPos->nNode.GetNode().GetContentNode()->MakeEndIndex( &pPos->nContent );
941 }
942 
943 bool GoInDoc( SwPaM & rPam, SwMoveFnCollection const & fnMove )
944 {
945  (*fnMove.fnDoc)( rPam.GetPoint() );
946  return true;
947 }
948 
949 bool GoInSection( SwPaM & rPam, SwMoveFnCollection const & fnMove )
950 {
951  (*fnMove.fnSections)( rPam.GetPoint() );
952  return true;
953 }
954 
955 bool GoInNode( SwPaM & rPam, SwMoveFnCollection const & fnMove )
956 {
957  SwContentNode *pNd = (*fnMove.fnNds)( &rPam.GetPoint()->nNode, true );
958  if( pNd )
959  rPam.GetPoint()->nContent.Assign( pNd,
960  ::GetSttOrEnd( &fnMove == &fnMoveForward, *pNd ) );
961  return pNd;
962 }
963 
964 bool GoInContent( SwPaM & rPam, SwMoveFnCollection const & fnMove )
965 {
966  if( (*fnMove.fnNd)( &rPam.GetPoint()->nNode.GetNode(),
967  &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS ))
968  return true;
969  return GoInNode( rPam, fnMove );
970 }
971 
972 bool GoInContentCells( SwPaM & rPam, SwMoveFnCollection const & fnMove )
973 {
974  if( (*fnMove.fnNd)( &rPam.GetPoint()->nNode.GetNode(),
975  &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS ))
976  return true;
977  return GoInNode( rPam, fnMove );
978 }
979 
980 bool GoInContentSkipHidden( SwPaM & rPam, SwMoveFnCollection const & fnMove )
981 {
982  if( (*fnMove.fnNd)( &rPam.GetPoint()->nNode.GetNode(),
984  return true;
985  return GoInNode( rPam, fnMove );
986 }
987 
989 {
990  if( (*fnMove.fnNd)( &rPam.GetPoint()->nNode.GetNode(),
992  return true;
993  return GoInNode( rPam, fnMove );
994 }
995 
996 bool GoPrevPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara )
997 {
998  if( rPam.Move( fnMoveBackward, GoInNode ) )
999  {
1000  // always on a ContentNode
1001  SwPosition& rPos = *rPam.GetPoint();
1002  SwContentNode * pNd = rPos.nNode.GetNode().GetContentNode();
1003  rPos.nContent.Assign( pNd,
1004  ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ) );
1005  return true;
1006  }
1007  return false;
1008 }
1009 
1010 bool GoCurrPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara )
1011 {
1012  SwPosition& rPos = *rPam.GetPoint();
1013  SwContentNode * pNd = rPos.nNode.GetNode().GetContentNode();
1014  if( pNd )
1015  {
1016  const sal_Int32 nOld = rPos.nContent.GetIndex();
1017  const sal_Int32 nNew = &aPosPara == &fnMoveForward ? 0 : pNd->Len();
1018  // if already at beginning/end then to the next/previous
1019  if( nOld != nNew )
1020  {
1021  rPos.nContent.Assign( pNd, nNew );
1022  return true;
1023  }
1024  }
1025  // move node to next/previous ContentNode
1026  if( ( &aPosPara==&fnParaStart && nullptr != ( pNd =
1027  GoPreviousNds( &rPos.nNode, true ))) ||
1028  ( &aPosPara==&fnParaEnd && nullptr != ( pNd =
1029  GoNextNds( &rPos.nNode, true ))) )
1030  {
1031  rPos.nContent.Assign( pNd,
1032  ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ));
1033  return true;
1034  }
1035  return false;
1036 }
1037 
1038 bool GoNextPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara )
1039 {
1040  if( rPam.Move( fnMoveForward, GoInNode ) )
1041  {
1042  // always on a ContentNode
1043  SwPosition& rPos = *rPam.GetPoint();
1044  SwContentNode * pNd = rPos.nNode.GetNode().GetContentNode();
1045  rPos.nContent.Assign( pNd,
1046  ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ) );
1047  return true;
1048  }
1049  return false;
1050 }
1051 
1052 bool GoCurrSection( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1053 {
1054  SwPosition& rPos = *rPam.GetPoint();
1055  SwPosition aSavePos( rPos ); // position for comparison
1056  (fnMove.fnSection)( &rPos.nNode );
1057  SwContentNode *pNd;
1058  if( nullptr == ( pNd = rPos.nNode.GetNode().GetContentNode()) &&
1059  nullptr == ( pNd = (*fnMove.fnNds)( &rPos.nNode, true )) )
1060  {
1061  rPos = aSavePos; // do not change cursor
1062  return false;
1063  }
1064 
1065  rPos.nContent.Assign( pNd,
1066  ::GetSttOrEnd( &fnMove == &fnMoveForward, *pNd ) );
1067  return aSavePos != rPos;
1068 }
1069 
1070 OUString SwPaM::GetText() const
1071 {
1072  OUStringBuffer aResult;
1073 
1074  SwNodeIndex aNodeIndex = Start()->nNode;
1075 
1076  // The first node can be already the end node.
1077  // Use a "forever" loop with an exit condition in the middle
1078  // of its body, in order to correctly handle all cases.
1079  bool bIsStartNode = true;
1080  for (;;)
1081  {
1082  const bool bIsEndNode = aNodeIndex == End()->nNode;
1083  SwTextNode * pTextNode = aNodeIndex.GetNode().GetTextNode();
1084 
1085  if (pTextNode != nullptr)
1086  {
1087  if (!bIsStartNode)
1088  {
1089  aResult.append(CH_TXTATR_NEWLINE); // use newline for para break
1090  }
1091  const OUString& aTmpStr = pTextNode->GetText();
1092 
1093  if (bIsStartNode || bIsEndNode)
1094  {
1095  // Handle corner cases of start/end node(s)
1096  const sal_Int32 nStart = bIsStartNode
1097  ? Start()->nContent.GetIndex()
1098  : 0;
1099  const sal_Int32 nEnd = bIsEndNode
1100  ? End()->nContent.GetIndex()
1101  : aTmpStr.getLength();
1102 
1103  aResult.append(std::u16string_view(aTmpStr).substr(nStart, nEnd-nStart));
1104  }
1105  else
1106  {
1107  aResult.append(aTmpStr);
1108  }
1109  }
1110 
1111  if (bIsEndNode)
1112  {
1113  break;
1114  }
1115 
1116  ++aNodeIndex;
1117  bIsStartNode = false;
1118  }
1119 
1120  return aResult.makeStringAndClear();
1121 }
1122 
1124 {
1125  for (SwNodeIndex index = Start()->nNode; index <= End()->nNode; ++index)
1126  {
1127  if (SwTextNode *const pTextNode = index.GetNode().GetTextNode())
1128  {
1129  // pretend that the PaM marks changed formatting to reformat...
1130  sal_Int32 const nStart(
1131  index == Start()->nNode ? Start()->nContent.GetIndex() : 0);
1132  // this should work even for length of 0
1133  SwUpdateAttr const aHint(
1134  nStart,
1135  index == End()->nNode
1136  ? End()->nContent.GetIndex() - nStart
1137  : pTextNode->Len() - nStart,
1138  0);
1139  pTextNode->TriggerNodeUpdate(sw::LegacyModifyHint(&aHint, &aHint));
1140  }
1141  // other node types not invalidated
1142  }
1143 }
1144 
1146 {
1147  xmlTextWriterStartElement(pWriter, BAD_CAST("SwPaM"));
1148 
1149  xmlTextWriterStartElement(pWriter, BAD_CAST("point"));
1150  GetPoint()->dumpAsXml(pWriter);
1151  xmlTextWriterEndElement(pWriter);
1152 
1153  if (HasMark())
1154  {
1155  xmlTextWriterStartElement(pWriter, BAD_CAST("mark"));
1156  GetMark()->dumpAsXml(pWriter);
1157  xmlTextWriterEndElement(pWriter);
1158  }
1159 
1160  xmlTextWriterEndElement(pWriter);
1161 }
1162 
1163 std::ostream &operator <<(std::ostream& s, const SwPaM& pam)
1164 {
1165  if( pam.HasMark())
1166  return s << "SwPaM (point " << *pam.GetPoint() << ", mark " << *pam.GetMark() << ")";
1167  else
1168  return s << "SwPaM (point " << *pam.GetPoint() << ")";
1169 }
1170 
1171 
1172 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:983
SwPosition m_Bound1
Definition: pam.hxx:138
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:685
Base class of the Writer layout elements.
Definition: frame.hxx:298
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
virtual sal_Int32 Len() const
Definition: node.cxx:1241
void DeleteMark()
Definition: pam.hxx:177
SwNode & GetEndOfInserts() const
Section for all footnotes.
Definition: ndarr.hxx:154
SwContentNode * GoNextNds(SwNodeIndex *pIdx, bool bChk)
Definition: pam.cxx:303
SwMoveFnCollection const & fnParaEnd
Definition: paminit.cxx:47
sal_uLong GetIndex() const
Definition: node.hxx:290
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
SwNode & GetEndOfAutotext() const
Section for all Flys/Header/Footers.
Definition: ndarr.hxx:156
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:964
Marks a position in the document model.
Definition: pam.hxx:35
SwContentNode * GetNode(SwPaM &rPam, bool &rbFirst, SwMoveFnCollection const &fnMove, bool const bInReadOnly, SwRootFrame const *const i_pLayout)
This function returns the next node in direction of search.
Definition: pam.cxx:817
bool IsInFly() const
Definition: frame.hxx:942
bool IsInSct() const
Definition: frame.hxx:948
sal_uLong StartOfSectionIndex() const
Definition: node.hxx:676
const OUString & GetText() const
Definition: ndtxt.hxx:211
virtual const SwRootFrame * GetCurrentLayout() const =0
std::unique_ptr< SwPaM > MakeRegion(SwMoveFnCollection const &fnMove, const SwPaM &rOrigRg)
make a new region
Definition: pam.cxx:522
virtual bool get(DocumentSettingId id) const override
Return the specified document setting.
bool GoCurrPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1010
static SwContentNode * GetContentNode(SwDoc &rDoc, SwNodeIndex &rIdx, bool bNext)
Definition: fltshell.cxx:53
SwNodeIndex nNode
Definition: pam.hxx:37
static sal_uInt16 GetSectionLevel(const SwNodeIndex &rIndex)
get section level at the given position
Definition: nodes.cxx:1252
GoSection fnSections
Definition: pamtyp.hxx:74
sal_uIntPtr sal_uLong
long Long
bool IsEditInReadonlyFlag() const
Definition: section.hxx:189
const SwPosition * GetMark() const
Definition: pam.hxx:209
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1208
sal_Int64 n
Provides access to the marks of a document.
Definition: doc.hxx:186
static SwContentNode * GoPrevSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true)
Definition: nodes.cxx:1959
SwMoveFnCollection const & fnParaStart
Definition: paminit.cxx:46
static CHKSECTION lcl_TstIdx(sal_uLong nSttIdx, sal_uLong nEndIdx, const SwNode &rEndNd)
Definition: pam.cxx:203
SwPosition * m_pPoint
points at either m_Bound1 or m_Bound2
Definition: pam.hxx:140
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1301
SwNode & GetNode() const
Definition: ndindex.hxx:119
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:31
#define CH_TXTATR_NEWLINE
Definition: hintids.hxx:172
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1705
Dialog to specify the properties of date form field.
SwNode & GetEndOfPostIts() const
A still empty section.
Definition: ndarr.hxx:152
CHKSECTION
Definition: pam.cxx:199
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: pam.cxx:1145
SwPosition * m_pMark
points at either m_Bound1 or m_Bound2
Definition: pam.hxx:141
void InvalidatePaM()
Definition: pam.cxx:1123
Array of Undo-history.
Definition: docary.hxx:197
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:188
const SwSection & GetSection() const
Definition: node.hxx:544
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
bool GoInSection(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:949
bool operator==(const SwPosition &) const
Definition: pam.cxx:167
void GoStartDoc(SwPosition *pPos)
Definition: pam.cxx:896
void GoEndSection(SwPosition *pPos)
go to the end of the current base section
Definition: pam.cxx:929
SwIndex nContent
Definition: pam.hxx:38
auto(*)(SwPaM &rPam, SwMoveFnCollection const &fnMove) -> bool SwGoInDoc
Definition: pam.hxx:126
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &pos) const =0
bool m_bIsInFrontOfLabel
Definition: pam.hxx:142
void GoEndDoc(SwPosition *pPos)
Definition: pam.cxx:906
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
bool IsStartNode() const
Definition: node.hxx:627
static void GoEndOfSection(SwNodeIndex *)
Definition: nodes.cxx:1278
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:257
bool IsProtectFlag() const
Definition: section.hxx:188
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1092
void Normalize(bool bPointFirst=true)
Normalizes PaM, i.e.
Definition: pam.cxx:539
MvSection fnSection
Definition: pamtyp.hxx:78
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:163
bool GoPrevPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:996
bool IsContentNode() const
Definition: node.hxx:631
OUString GetText() const
Definition: pam.cxx:1070
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
struct _xmlTextWriter * xmlTextWriterPtr
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:502
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
SwPaM(SwPaM const &rPaM)=delete
bool operator!=(const SwPosition &) const
Definition: pam.cxx:173
bool GoNext(SwNode *pNd, SwIndex *pIdx, sal_uInt16 nMode)
Definition: pam.cxx:289
int i
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:955
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
SwDoc & GetDoc()
Definition: node.hxx:211
const SwPosition * GetPoint() const
Definition: pam.hxx:207
std::vector< SwSectionFormat * >::size_type size_type
Definition: docary.hxx:63
bool GoInContentCells(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:972
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:328
SwPageFrame * FindPageFrame()
Definition: frame.hxx:663
bool operator>=(const SwPosition &) const
Definition: pam.cxx:145
static void GoStartOfSection(SwNodeIndex *)
Definition: nodes.cxx:1260
bool GoInContentCellsSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:988
void Exchange()
Definition: pam.cxx:490
SwPosition(const SwNodeIndex &rNode, const SwIndex &rContent)
Definition: pam.cxx:59
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwContentNode * GetContentNode()
Definition: node.hxx:618
SwSection * GetSection()
Definition: sectfrm.hxx:82
SwPosition m_Bound2
Definition: pam.hxx:139
void MakeStartIndex(SwIndex *pIdx)
Definition: node.hxx:399
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
const sal_uInt16 CRSR_SKIP_HIDDEN
Definition: swcrsr.hxx:67
Marks a character position inside a document model node.
Definition: index.hxx:33
size_t size() const
Definition: docary.hxx:84
bool IsContentProtected() const
bool GoCurrSection(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1052
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:696
bool GoInDoc(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:943
tuple index
virtual ~SwPaM() override
Definition: pam.cxx:446
A page of the document layout.
Definition: pagefrm.hxx:41
bool operator>(const SwPosition &) const
Definition: pam.cxx:101
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
virtual bool isBookmarkDeleted(SwPaM const &rPaM) const =0
check if the selection would delete a BOOKMARK
const SwPosition * Start() const
Definition: pam.hxx:212
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1096
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
bool GoInContentSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:980
const sal_uInt16 CRSR_SKIP_CELLS
Definition: swcrsr.hxx:66
#define ODF_UNHANDLED
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:680
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:67
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
const SwNodes & GetNodes() const
Definition: ndindex.hxx:156
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
sal_Int32 GetIndex() const
Definition: index.hxx:91
bool IsNoTextFrame() const
Definition: frame.hxx:1219
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
std::ostream & operator<<(std::ostream &s, const SwPosition &position)
Definition: pam.cxx:192
const SwPosition * End() const
Definition: pam.hxx:217
SwDoc & GetDoc() const
Returns the document this position is in.
Definition: pam.cxx:179
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:186
bool GoNextPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1038
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: pam.cxx:184
bool HasReadonlySel(bool bFormView) const
Is in something protected (readonly) or selection contains something protected.
Definition: pam.cxx:596
bool operator<=(const SwPosition &) const
Definition: pam.cxx:123
static bool lcl_ChkOneRange(CHKSECTION eSec, bool bChkSections, const SwNode &rBaseEnd, sal_uLong nStt, sal_uLong nEnd)
Definition: pam.cxx:212
SwPaM & operator=(const SwPaM &)
@@ semantic: no copy assignment for super class Ring.
Definition: pam.cxx:458
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
void GoStartSection(SwPosition *pPos)
Definition: pam.cxx:915
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
bool operator<(const SwPosition &) const
Definition: pam.cxx:79
const sal_uInt16 CRSR_SKIP_CHARS
Definition: swcrsr.hxx:65
virtual OUString GetFieldname() const =0
SwContentNode * GoNextSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true) const
Go to next content-node that is not protected or hidden (Both set FALSE ==> GoNext/GoPrevious!!!).
Definition: nodes.cxx:1907
SwContentNode * GoPreviousNds(SwNodeIndex *pIdx, bool bChk)
Definition: pam.cxx:318
bool IsCursorInParagraphMetadataField() const
Returns true iff the cursor is within a paragraph metadata field.
Definition: edfcol.cxx:2042
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc...
Definition: nodes.cxx:2320
const SvxProtectItem & GetProtect(bool=true) const
Definition: frmatr.hxx:82
SwDoc & GetDoc() const
Definition: pam.hxx:243
SwSectionNode * GetSectionNode()
Definition: node.hxx:610
virtual const SwPosition & GetMarkStart() const =0
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:476
SwNode & GetEndOfRedlines() const
Section for all Redlines.
Definition: ndarr.hxx:158
const SwIndexReg * GetIdxReg() const
Definition: index.hxx:97
SwSectionFormats & GetSections()
Definition: doc.hxx:1338
bool GoPrevious(SwNode *pNd, SwIndex *pIdx, sal_uInt16 nMode)
Definition: pam.cxx:296
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1284
void MakeEndIndex(SwIndex *pIdx)
Definition: node.hxx:400
sal_uInt16 GetPageNum(bool bAtPoint=true, const Point *pLayPos=nullptr)
Get number of page which contains cursor.
Definition: pam.cxx:550
static sal_Int32 GetSttOrEnd(bool bCondition, const SwContentNode &rNd)
Definition: pam.cxx:54
std::pair< SwTextNode *, SwTextNode * > GetFirstAndLastNode(SwRootFrame const &rLayout, SwNodeIndex const &rPos)
Definition: txtfrm.cxx:351
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:846
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1627
Base class of the Writer document model elements.
Definition: node.hxx:79
static const SwFrame * lcl_FindEditInReadonlyFrame(const SwFrame &rFrame)
Definition: pam.cxx:571