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