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