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