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 <utility>
49#include <xmloff/odffields.hxx>
50#include <rtl/ustrbuf.hxx>
51
52#include <editsh.hxx>
54
55// for the dump "MSC-" compiler
56static sal_Int32 GetSttOrEnd( bool bCondition, const SwContentNode& rNd )
57{
58 return bCondition ? 0 : rNd.Len();
59}
60
61SwPosition::SwPosition( const SwNodeIndex & rNodeIndex, const SwContentIndex & rContent )
62 : nNode( rNodeIndex ), nContent( rContent )
63{
64 assert((!rNodeIndex.GetNode().GetContentNode() || rNodeIndex.GetNode().GetContentNode() == rContent.GetContentNode())
65 && "parameters point to different nodes");
66}
67
68SwPosition::SwPosition( const SwNode & rNode, const SwContentIndex & rContent )
69 : nNode( rNode ), nContent( rContent )
70{
71 assert((!rNode.GetContentNode() || rNode.GetContentNode() == rContent.GetContentNode())
72 && "parameters point to different nodes");
73}
74
75SwPosition::SwPosition( const SwNodeIndex & rNodeIndex, const SwContentNode* pContentNode, sal_Int32 nContentOffset )
76 : nNode( rNodeIndex ), nContent( pContentNode, nContentOffset )
77{
78 assert((!pContentNode || pContentNode == &rNodeIndex.GetNode()) &&
79 "parameters point to different nodes");
80}
81
82SwPosition::SwPosition( const SwNode & rNode, const SwContentNode* pContentNode, sal_Int32 nContentOffset )
83 : nNode( rNode ), nContent( pContentNode, nContentOffset )
84{
85 assert((!pContentNode || pContentNode == &rNode) &&
86 "parameters point to different nodes");
87}
88
89SwPosition::SwPosition( const SwNodeIndex & rNodeIndex, SwNodeOffset nDiff, const SwContentNode* pContentNode, sal_Int32 nContentOffset )
90 : nNode( rNodeIndex, nDiff ), nContent( pContentNode, nContentOffset )
91{
92 assert((!pContentNode || pContentNode == &rNodeIndex.GetNode()) &&
93 "parameters point to different nodes");
94}
95
97 : nNode( rNodeIndex, nDiff ), nContent( GetNode().GetContentNode() )
98{
99}
100
102 : nNode( rNode, nDiff ), nContent( GetNode().GetContentNode() )
103{
104}
105
107 : nNode( rNodes, nIndex ), nContent( GetNode().GetContentNode() )
108{
109}
110
111SwPosition::SwPosition( const SwContentNode & rNode, const sal_Int32 nContentOffset )
112 : nNode( rNode ), nContent( &rNode, nContentOffset )
113{
114}
115
116SwPosition::SwPosition( const SwContentIndex & rContentIndex, short nDiff )
117 : nNode( *rContentIndex.GetContentNode() ), nContent( rContentIndex, nDiff )
118{
119}
120
121bool SwPosition::operator<(const SwPosition &rPos) const
122{
123 // cheaper to check for == first
124 if( nNode == rPos.nNode )
125 {
126 // note that positions with text node but no SwContentIndex registered are
127 // created for text frames anchored at para (see SwXFrame::getAnchor())
128 SwContentNode const*const pThisReg(GetContentNode());
129 SwContentNode const*const pOtherReg(rPos.GetContentNode());
130 if (pThisReg && pOtherReg)
131 {
132 return (nContent < rPos.nContent);
133 }
134 else // by convention position with no index is smaller
135 {
136 return pOtherReg != nullptr;
137 }
138 }
139 return nNode < rPos.nNode;
140}
141
142bool SwPosition::operator>(const SwPosition &rPos) const
143{
144 // cheaper to check for == first
145 if( nNode == rPos.nNode )
146 {
147 // note that positions with text node but no SwContentIndex registered are
148 // created for text frames anchored at para (see SwXFrame::getAnchor())
149 SwContentNode const*const pThisReg(GetContentNode());
150 SwContentNode const*const pOtherReg(rPos.GetContentNode());
151 if (pThisReg && pOtherReg)
152 {
153 return (nContent > rPos.nContent);
154 }
155 else // by convention position with no index is smaller
156 {
157 return pThisReg != nullptr;
158 }
159 }
160 return nNode > rPos.nNode;
161}
162
163bool SwPosition::operator<=(const SwPosition &rPos) const
164{
165 // cheaper to check for == first
166 if( nNode == rPos.nNode )
167 {
168 // note that positions with text node but no SwContentIndex registered are
169 // created for text frames anchored at para (see SwXFrame::getAnchor())
170 SwContentNode const*const pThisReg(GetContentNode());
171 SwContentNode const*const pOtherReg(rPos.GetContentNode());
172 if (pThisReg && pOtherReg)
173 {
174 return (nContent <= rPos.nContent);
175 }
176 else // by convention position with no index is smaller
177 {
178 return pThisReg == nullptr;
179 }
180 }
181 return nNode < rPos.nNode;
182}
183
184bool SwPosition::operator>=(const SwPosition &rPos) const
185{
186 // cheaper to check for == first
187 if( nNode == rPos.nNode )
188 {
189 // note that positions with text node but no SwContentIndex registered are
190 // created for text frames anchored at para (see SwXFrame::getAnchor())
191 SwContentNode const*const pThisReg(GetContentNode());
192 SwContentNode const*const pOtherReg(rPos.GetContentNode());
193 if (pThisReg && pOtherReg)
194 {
195 return (nContent >= rPos.nContent);
196 }
197 else // by convention position with no index is smaller
198 {
199 return pOtherReg == nullptr;
200 }
201 }
202 return nNode > rPos.nNode;
203}
204
205bool SwPosition::operator==(const SwPosition &rPos) const
206{
207 return (nNode == rPos.nNode)
208 && (nContent == rPos.nContent);
209}
210
211bool SwPosition::operator!=(const SwPosition &rPos) const
212{
213 return (nNode != rPos.nNode)
214 || (nContent != rPos.nContent);
215}
216
218{
219 return GetNode().GetDoc();
220}
221
223{
224 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwPosition"));
225 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nNode"), BAD_CAST(OString::number(sal_Int32(GetNodeIndex())).getStr()));
226 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nContent"), BAD_CAST(OString::number(GetContentIndex()).getStr()));
227 (void)xmlTextWriterEndElement(pWriter);
228}
229
230void SwPosition::Assign( const SwNode& rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset )
231{
232 nNode.Assign(rNd, nDelta);
233 assert((nNode.GetNode().GetContentNode() || nContentOffset == 0) && "setting contentoffset, but node is not SwContentNode");
234 nContent.Assign(nNode.GetNode().GetContentNode(), nContentOffset);
235}
236void SwPosition::Assign( SwNodeOffset nNodeOffset, sal_Int32 nContentOffset )
237{
238 nNode = nNodeOffset;
239 nContent.Assign(nNode.GetNode().GetContentNode(), nContentOffset);
240}
241void SwPosition::Assign( const SwContentNode& rNode, sal_Int32 nContentOffset )
242{
243 nNode = rNode;
244 nContent.Assign(&rNode, nContentOffset);
245}
246void SwPosition::Assign( const SwNode& rNd, sal_Int32 nContentOffset )
247{
248 nNode.Assign(rNd);
249 nContent.Assign(rNd.GetContentNode(), nContentOffset);
250}
251void SwPosition::Assign( const SwNodeIndex& rNdIdx, sal_Int32 nContentOffset )
252{
253 nNode = rNdIdx;
254 nContent.Assign(nNode.GetNode().GetContentNode(), nContentOffset);
255}
257{
258 nNode += nDelta;
260}
261void SwPosition::AdjustContent( sal_Int32 nDelta )
262{
263 assert(nNode.GetNode().GetContentNode() && "only valid to call this if we point to an SwContentNode");
264 nContent += nDelta;
265}
266void SwPosition::SetContent( sal_Int32 nContentIndex )
267{
268 assert(nNode.GetNode().GetContentNode() && "only valid to call this if we point to an SwContentNode");
269 nContent = nContentIndex;
270}
272{
273 nNode = rNd;
274 nContent.Assign(&rNd, 0);
275}
277{
278 nNode = rNd;
279 nContent.Assign(&rNd, rNd.Len());
280}
281
282
283std::ostream &operator <<(std::ostream& s, const SwPosition& position)
284{
285 return s << "SwPosition (node " << position.GetNodeIndex() << ", offset " << position.GetContentIndex() << ")";
286}
287
288namespace {
289
290enum CHKSECTION { Chk_Both, Chk_One, Chk_None };
291
292}
293
294static CHKSECTION lcl_TstIdx( SwNodeOffset nSttIdx, SwNodeOffset nEndIdx, const SwNode& rEndNd )
295{
296 SwNodeOffset nStt = rEndNd.StartOfSectionIndex(), nEnd = rEndNd.GetIndex();
297 CHKSECTION eSec = nStt < nSttIdx && nEnd >= nSttIdx ? Chk_One : Chk_None;
298 if( nStt < nEndIdx && nEnd >= nEndIdx )
299 return( eSec == Chk_One ? Chk_Both : Chk_One );
300 return eSec;
301}
302
303static bool lcl_ChkOneRange( CHKSECTION eSec, bool bChkSections,
304 const SwNode& rBaseEnd, SwNodeOffset nStt, SwNodeOffset nEnd )
305{
306 if( eSec != Chk_Both )
307 return false;
308
309 if( !bChkSections )
310 return true;
311
312 // search the surrounding section
313 const SwNodes& rNds = rBaseEnd.GetNodes();
314 const SwNode *pTmp, *pNd = rNds[ nStt ];
315 if( !pNd->IsStartNode() )
316 pNd = pNd->StartOfSectionNode();
317
318 if( pNd == rNds[ nEnd ]->StartOfSectionNode() )
319 return true; // same StartNode, same section
320
321 // already on a base node => error
322 if( !pNd->StartOfSectionIndex() )
323 return false;
324
325 for (;;)
326 {
327 pTmp = pNd->StartOfSectionNode();
328 if (pTmp->EndOfSectionNode() == &rBaseEnd )
329 break;
330 pNd = pTmp;
331 }
332
333 SwNodeOffset nSttIdx = pNd->GetIndex(), nEndIdx = pNd->EndOfSectionIndex();
334 return nSttIdx <= nStt && nStt <= nEndIdx &&
335 nSttIdx <= nEnd && nEnd <= nEndIdx;
336}
337
348bool CheckNodesRange( const SwNode& rStt,
349 const SwNode& rEnd, bool bChkSection )
350{
351 const SwNodes& rNds = rStt.GetNodes();
352 SwNodeOffset nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
353 CHKSECTION eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfContent() );
354 if( Chk_None != eSec )
355 return eSec == Chk_Both;
356
357 eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfAutotext() );
358 if( Chk_None != eSec )
359 return lcl_ChkOneRange( eSec, bChkSection,
360 rNds.GetEndOfAutotext(), nStt, nEnd );
361
362 eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfPostIts() );
363 if( Chk_None != eSec )
364 return lcl_ChkOneRange( eSec, bChkSection,
365 rNds.GetEndOfPostIts(), nStt, nEnd );
366
367 eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfInserts() );
368 if( Chk_None != eSec )
369 return lcl_ChkOneRange( eSec, bChkSection,
370 rNds.GetEndOfInserts(), nStt, nEnd );
371
372 eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfRedlines() );
373 if( Chk_None != eSec )
374 return lcl_ChkOneRange( eSec, bChkSection,
375 rNds.GetEndOfRedlines(), nStt, nEnd );
376
377 return false; // somewhere in between => error
378}
379
381{
382 if( pNd->IsContentNode() )
383 return static_cast<SwContentNode*>(pNd)->GoNext( pIdx, nMode );
384 return false;
385}
386
388{
389 if( pNd->IsContentNode() )
390 return static_cast<SwContentNode*>(pNd)->GoPrevious( pIdx, nMode );
391 return false;
392}
393
395{
396 SwNodeIndex aIdx( *pIdx );
397 SwContentNode* pNd = aIdx.GetNodes().GoNext( &aIdx );
398 if( pNd )
399 {
400 if( bChk && SwNodeOffset(1) != aIdx.GetIndex() - pIdx->GetIndex() &&
401 !CheckNodesRange( pIdx->GetNode(), aIdx.GetNode(), true ) )
402 pNd = nullptr;
403 else
404 *pIdx = aIdx;
405 }
406 return pNd;
407}
408
410{
411 SwNodeIndex aIdx( *pIdx );
412 SwContentNode* pNd = SwNodes::GoPrevious( &aIdx );
413 if( pNd )
414 {
415 if( bChk && SwNodeOffset(1) != pIdx->GetIndex() - aIdx.GetIndex() &&
416 !CheckNodesRange( pIdx->GetNode(), aIdx.GetNode(), true ) )
417 pNd = nullptr;
418 else
419 *pIdx = aIdx;
420 }
421 return pNd;
422}
423
425{
426 SwNodeIndex aIdx( pIdx->GetNode() );
427 SwContentNode* pNd = aIdx.GetNodes().GoNext( &aIdx );
428 if( pNd )
429 {
430 if( bChk && SwNodeOffset(1) != aIdx.GetIndex() - pIdx->GetNodeIndex() &&
431 !CheckNodesRange( pIdx->GetNode(), aIdx.GetNode(), true ) )
432 pNd = nullptr;
433 else
434 pIdx->Assign(aIdx);
435 }
436 return pNd;
437}
438
440{
441 SwNodeIndex aIdx( pIdx->GetNode() );
442 SwContentNode* pNd = SwNodes::GoPrevious( &aIdx );
443 if( pNd )
444 {
445 if( bChk && SwNodeOffset(1) != pIdx->GetNodeIndex() - aIdx.GetIndex() &&
446 !CheckNodesRange( pIdx->GetNode(), aIdx.GetNode(), true ) )
447 pNd = nullptr;
448 else
449 pIdx->Assign(aIdx);
450 }
451 return pNd;
452}
453
454SwPaM::SwPaM( const SwPosition& rPos, SwPaM* pRing )
455 : Ring( pRing )
456 , m_Bound1( rPos )
457 , m_Bound2( rPos.GetNode().GetNodes() ) // default initialize
458 , m_pPoint( &m_Bound1 )
459 , m_pMark( m_pPoint )
460 , m_bIsInFrontOfLabel( false )
461{
462}
463
464SwPaM::SwPaM( const SwPosition& rMark, const SwPosition& rPoint, SwPaM* pRing )
465 : Ring( pRing )
466 , m_Bound1( rMark )
467 , m_Bound2( rPoint )
468 , m_pPoint( &m_Bound2 )
469 , m_pMark( &m_Bound1 )
470 , m_bIsInFrontOfLabel( false )
471{
472}
473
474SwPaM::SwPaM( const SwNodeIndex& rMark, const SwNodeIndex& rPoint,
475 SwNodeOffset nMarkOffset, SwNodeOffset nPointOffset, SwPaM* pRing )
476 : Ring( pRing )
477 , m_Bound1( rMark )
478 , m_Bound2( rPoint )
479 , m_pPoint( &m_Bound2 )
480 , m_pMark( &m_Bound1 )
481 , m_bIsInFrontOfLabel( false )
482{
483 if ( nMarkOffset )
484 {
485 m_pMark->nNode += nMarkOffset;
486 }
487 if ( nPointOffset )
488 {
489 m_pPoint->nNode += nPointOffset;
490 }
493}
494
495SwPaM::SwPaM( const SwNode& rMark, const SwNode& rPoint,
496 SwNodeOffset nMarkOffset, SwNodeOffset nPointOffset, SwPaM* pRing )
497 : Ring( pRing )
498 , m_Bound1( rMark )
499 , m_Bound2( rPoint )
500 , m_pPoint( &m_Bound2 )
501 , m_pMark( &m_Bound1 )
502 , m_bIsInFrontOfLabel( false )
503{
504 if ( nMarkOffset )
505 {
506 m_pMark->nNode += nMarkOffset;
507 }
508 if ( nPointOffset )
509 {
510 m_pPoint->nNode += nPointOffset;
511 }
514}
515
516SwPaM::SwPaM( const SwNodeIndex& rMark, sal_Int32 nMarkContent,
517 const SwNodeIndex& rPoint, sal_Int32 nPointContent, SwPaM* pRing )
518 : Ring( pRing )
519 , m_Bound1( rMark )
520 , m_Bound2( rPoint )
521 , m_pPoint( &m_Bound2 )
522 , m_pMark( &m_Bound1 )
523 , m_bIsInFrontOfLabel( false )
524{
525 m_pPoint->nContent.Assign( rPoint.GetNode().GetContentNode(), nPointContent);
526 m_pMark ->nContent.Assign( rMark .GetNode().GetContentNode(), nMarkContent );
527}
528
529SwPaM::SwPaM( const SwNode& rMark, sal_Int32 nMarkContent,
530 const SwNode& rPoint, sal_Int32 nPointContent, SwPaM* pRing )
531 : Ring( pRing )
532 , m_Bound1( rMark )
533 , m_Bound2( rPoint )
534 , m_pPoint( &m_Bound2 )
535 , m_pMark( &m_Bound1 )
536 , m_bIsInFrontOfLabel( false )
537{
539 nPointContent);
541 nMarkContent );
542}
543
544SwPaM::SwPaM( const SwNode& rMark, SwNodeOffset nMarkOffset, sal_Int32 nMarkContent,
545 const SwNode& rPoint, SwNodeOffset nPointOffset, sal_Int32 nPointContent, SwPaM* pRing )
546 : Ring( pRing )
547 , m_Bound1( rMark )
548 , m_Bound2( rPoint )
549 , m_pPoint( &m_Bound2 )
550 , m_pMark( &m_Bound1 )
551 , m_bIsInFrontOfLabel( false )
552{
553 if ( nMarkOffset )
554 {
555 m_pMark->nNode += nMarkOffset;
556 }
557 if ( nPointOffset )
558 {
559 m_pPoint->nNode += nPointOffset;
560 }
562 nPointContent);
564 nMarkContent );
565}
566
567SwPaM::SwPaM( const SwNode& rNode, sal_Int32 nContent, SwPaM* pRing )
568 : Ring( pRing )
569 , m_Bound1( rNode )
570 , m_Bound2( m_Bound1.GetNode().GetNodes() ) // default initialize
571 , m_pPoint( &m_Bound1 )
572 , m_pMark( &m_Bound1 )
573 , m_bIsInFrontOfLabel( false )
574{
576 nContent );
577}
578
579SwPaM::SwPaM( const SwNode& rNode, SwNodeOffset nNdOffset, sal_Int32 nContent, SwPaM* pRing )
580 : Ring( pRing )
581 , m_Bound1( rNode, nNdOffset )
582 , m_Bound2( m_Bound1.GetNode().GetNodes() ) // default initialize
583 , m_pPoint( &m_Bound1 )
584 , m_pMark( &m_Bound1 )
585 , m_bIsInFrontOfLabel( false )
586{
588 nContent );
589}
590
591SwPaM::SwPaM( const SwNodeIndex& rNodeIdx, sal_Int32 nContent, SwPaM* pRing )
592 : Ring( pRing )
593 , m_Bound1( rNodeIdx )
594 , m_Bound2( rNodeIdx.GetNode().GetNodes() ) // default initialize
595 , m_pPoint( &m_Bound1 )
596 , m_pMark( &m_Bound1 )
597 , m_bIsInFrontOfLabel( false )
598{
599 m_pPoint->nContent.Assign( rNodeIdx.GetNode().GetContentNode(), nContent );
600}
601
602SwPaM::SwPaM( SwNodes& rNodes, SwNodeOffset nNdOffset, SwPaM* pRing )
603 : Ring( pRing )
604 , m_Bound1( rNodes, nNdOffset )
605 , m_Bound2( rNodes ) // default initialize
606 , m_pPoint( &m_Bound1 )
607 , m_pMark( &m_Bound1 )
608 , m_bIsInFrontOfLabel( false )
609{
610}
611
613
614SwPaM::SwPaM(SwPaM const& rPam, SwPaM *const pRing)
615 : Ring(pRing)
616 , m_Bound1( *(rPam.m_pPoint) )
617 , m_Bound2( *(rPam.m_pMark) )
618 , m_pPoint( &m_Bound1 ), m_pMark( rPam.HasMark() ? &m_Bound2 : m_pPoint )
619 , m_bIsInFrontOfLabel( false )
620{
621}
622
623// @@@ semantic: no copy assignment for super class Ring.
625{
626 if(this == &rPam)
627 return *this;
628
629 *m_pPoint = *( rPam.m_pPoint );
630 if ( rPam.HasMark() )
631 {
632 SetMark();
633 *m_pMark = *( rPam.m_pMark );
634 }
635 else
636 {
637 DeleteMark();
638 }
639 return *this;
640}
641
643{
644 if (m_pPoint == &m_Bound1)
645 {
646 m_pMark = &m_Bound2;
647 }
648 else
649 {
650 m_pMark = &m_Bound1;
651 }
652 (*m_pMark) = *m_pPoint;
653}
654
655#ifdef DBG_UTIL
657{
658 if (m_pPoint != m_pMark)
659 {
660 SwPosition *pTmp = m_pPoint;
662 m_pMark = pTmp;
663 }
664}
665#endif
666
668bool SwPaM::Move( SwMoveFnCollection const & fnMove, SwGoInDoc fnGo )
669{
670 const bool bRet = (*fnGo)( *this, fnMove );
671
672 m_bIsInFrontOfLabel = false;
673 return bRet;
674}
675
676namespace sw {
677
687void MakeRegion(SwMoveFnCollection const & fnMove,
688 const SwPaM & rOrigRg, std::optional<SwPaM>& rPam)
689{
690 rPam.emplace(rOrigRg, const_cast<SwPaM*>(&rOrigRg)); // given search range
691 // make sure that SPoint is on the "real" start position
692 // FORWARD: SPoint always smaller than GetMark
693 // BACKWARD: SPoint always bigger than GetMark
694 if( (rPam->GetMark()->*fnMove.fnCmpOp)( *rPam->GetPoint() ) )
695 rPam->Exchange();
696}
697
698} // namespace sw
699
700void SwPaM::Normalize(bool bPointFirst)
701{
702 if (HasMark())
703 if ( ( bPointFirst && *m_pPoint > *m_pMark) ||
704 (!bPointFirst && *m_pPoint < *m_pMark) )
705 {
706 Exchange();
707 }
708}
709
711sal_uInt16 SwPaM::GetPageNum( bool bAtPoint, const Point* pLayPos )
712{
713 const SwContentFrame* pCFrame;
714 const SwPageFrame *pPg;
715 const SwContentNode *pNd ;
716 const SwPosition* pPos = bAtPoint ? m_pPoint : m_pMark;
717
718 std::pair<Point, bool> tmp;
719 if (pLayPos)
720 {
721 tmp.first = *pLayPos;
722 tmp.second = false;
723 }
724 if( nullptr != ( pNd = pPos->GetNode().GetContentNode() ) &&
725 nullptr != (pCFrame = pNd->getLayoutFrame(pNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), pPos, pLayPos ? &tmp : nullptr)) &&
726 nullptr != ( pPg = pCFrame->FindPageFrame() ))
727 return pPg->GetPhyPageNum();
728 return 0;
729}
730
731// form view - see also SwCursorShell::IsCursorReadonly()
732static const SwFrame* lcl_FindEditInReadonlyFrame( const SwFrame& rFrame )
733{
734 const SwFrame* pRet = nullptr;
735
736 const SwFlyFrame* pFly;
737 const SwSectionFrame* pSectionFrame;
738
739 if( rFrame.IsInFly() &&
740 (pFly = rFrame.FindFlyFrame())->GetFormat()->GetEditInReadonly().GetValue() &&
741 pFly->Lower() &&
742 !pFly->Lower()->IsNoTextFrame() )
743 {
744 pRet = pFly;
745 }
746 else if ( rFrame.IsInSct() &&
747 nullptr != ( pSectionFrame = rFrame.FindSctFrame() )->GetSection() &&
748 pSectionFrame->GetSection()->IsEditInReadonlyFlag() )
749 {
750 pRet = pSectionFrame;
751 }
752
753 return pRet;
754}
755
757bool SwPaM::HasReadonlySel(bool bFormView, bool const isReplace) const
758{
759 bool bRet = false;
760
761 const SwContentNode* pNd = GetPoint()->GetNode().GetContentNode();
762 const SwContentFrame *pFrame = nullptr;
763 if ( pNd != nullptr )
764 {
765 Point aTmpPt;
766 std::pair<Point, bool> const tmp(aTmpPt, false);
767 pFrame = pNd->getLayoutFrame(
769 GetPoint(), &tmp);
770 }
771
772 // Will be set if point are inside edit-in-readonly environment
773 const SwFrame* pPointEditInReadonlyFrame = nullptr;
774 if ( pFrame != nullptr
775 && ( pFrame->IsProtected()
776 || ( bFormView
777 && nullptr == ( pPointEditInReadonlyFrame = lcl_FindEditInReadonlyFrame( *pFrame ) ) ) ) )
778 {
779 bRet = true;
780 }
781 else if( pNd != nullptr )
782 {
783 const SwSectionNode* pSNd = pNd->GetSectionNode();
784 if ( pSNd != nullptr
785 && ( pSNd->GetSection().IsProtectFlag()
786 || ( bFormView
787 && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
788 {
789 bRet = true;
790 }
791 else
792 {
793 const SwSectionNode* pParentSectionNd = pNd->FindSectionNode();
794 if ( pParentSectionNd != nullptr
795 && ( pParentSectionNd->GetSection().IsProtectFlag()
796 || ( bFormView && !pParentSectionNd->GetSection().IsEditInReadonlyFlag()) ) )
797 {
798 bRet = true;
799 }
800 }
801 }
802
803 if ( !bRet
804 && HasMark()
805 && GetPoint()->nNode != GetMark()->nNode )
806 {
807 pNd = GetMark()->GetNode().GetContentNode();
808 pFrame = nullptr;
809 if ( pNd != nullptr )
810 {
811 Point aTmpPt;
812 std::pair<Point, bool> const tmp(aTmpPt, false);
813 pFrame = pNd->getLayoutFrame(
815 GetMark(), &tmp);
816 }
817
818 const SwFrame* pMarkEditInReadonlyFrame = nullptr;
819 if ( pFrame != nullptr
820 && ( pFrame->IsProtected()
821 || ( bFormView
822 && nullptr == ( pMarkEditInReadonlyFrame = lcl_FindEditInReadonlyFrame( *pFrame ) ) ) ) )
823 {
824 bRet = true;
825 }
826 else if( pNd != nullptr )
827 {
828 const SwSectionNode* pSNd = pNd->GetSectionNode();
829 if ( pSNd != nullptr
830 && ( pSNd->GetSection().IsProtectFlag()
831 || ( bFormView
832 && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
833 {
834 bRet = true;
835 }
836 }
837
838 if ( !bRet && bFormView )
839 {
840 // Check if start and end frame are inside the _same_
841 // edit-in-readonly-environment. Otherwise we better return 'true'
842 if ( pPointEditInReadonlyFrame != pMarkEditInReadonlyFrame )
843 bRet = true;
844 }
845
846 // check for protected section inside the selection
847 if( !bRet )
848 {
849 SwNodeOffset nSttIdx = GetMark()->GetNodeIndex(),
850 nEndIdx = GetPoint()->GetNodeIndex();
851 if( nEndIdx < nSttIdx )
852 std::swap( nSttIdx, nEndIdx );
853
854 // If a protected section should be between nodes, then the
855 // selection needs to contain already x nodes.
856 // (TextNd, SectNd, TextNd, EndNd, TextNd )
857 if( nSttIdx + SwNodeOffset(3) < nEndIdx )
858 {
859 const SwSectionFormats& rFormats = GetDoc().GetSections();
860 for( SwSectionFormats::size_type n = rFormats.size(); n; )
861 {
862 const SwSectionFormat* pFormat = rFormats[ --n ];
863 if( pFormat->GetProtect().IsContentProtected() )
864 {
865 const SwFormatContent& rContent = pFormat->GetContent(false);
866 OSL_ENSURE( rContent.GetContentIdx(), "where is the SectionNode?" );
867 SwNodeOffset nIdx = rContent.GetContentIdx()->GetIndex();
868 if( nSttIdx <= nIdx && nEndIdx >= nIdx &&
869 rContent.GetContentIdx()->GetNode().GetNodes().IsDocNodes() )
870 {
871 bRet = true;
872 break;
873 }
874 }
875 }
876 }
877 }
878 }
879
880 const SwDoc& rDoc = GetDoc();
881 // Legacy text/combo/checkbox: never return read-only when inside these form fields.
882 const IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess();
883 sw::mark::IFieldmark* pA = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : nullptr;
884 sw::mark::IFieldmark* pB = GetMark() ? pMarksAccess->getFieldmarkFor( *GetMark( ) ) : pA;
885 // prevent the user from accidentally deleting the field itself when modifying the text.
886 const bool bAtStartA = (pA != nullptr) && (pA->GetMarkStart() == *GetPoint());
887 const bool bAtStartB = (pB != nullptr) && (pB->GetMarkStart() == *GetMark());
888
890 {
891 ; // allow editing all fields in generic mode
892 }
893 else if (!bRet)
894 {
895 bool bUnhandledMark = pA && pA->GetFieldname( ) == ODF_UNHANDLED;
896 // Unhandled fieldmarks case shouldn't be edited manually to avoid breaking anything
897 if ( ( pA == pB ) && bUnhandledMark )
898 bRet = true;
899 else
900 {
901 if ((pA == pB) && (bAtStartA != bAtStartB))
902 bRet = true;
903 else if (pA != pB)
904 {
905 // If both points are either outside or at marks edges (i.e. selection either
906 // touches fields, or fully encloses it), then don't disable editing
907 bRet = !( ( !pA || bAtStartA ) && ( !pB || bAtStartB ) );
908 }
909 if( !bRet && rDoc.GetDocumentSettingManager().get( DocumentSettingId::PROTECT_FORM ) && (pA || pB) )
910 {
911 // Form protection case
912 bRet = ( pA == nullptr ) || ( pB == nullptr ) || bAtStartA || bAtStartB;
913 }
914 }
915 }
916 else
917 {
918 // Allow editing when the cursor/selection is fully inside of a legacy form field.
919 bRet = !( pA != nullptr && !bAtStartA && !bAtStartB && pA == pB );
920
921 if (bRet)
922 {
923 // Also allow editing inside content controls in general, similar to form fields.
924 // Specific types will be disabled below.
925 if (const SwEditShell* pEditShell = rDoc.GetEditShell())
926 bRet = !pEditShell->CursorInsideContentControl();
927 }
928 }
929
930 if (!bRet)
931 {
932 // Paragraph Signatures and Classification fields are read-only.
933 if (const SwEditShell* pEditShell = rDoc.GetEditShell())
934 bRet = pEditShell->IsCursorInParagraphMetadataField();
935 }
936
937 if (!bRet &&
939 {
940 if (rDoc.getIDocumentMarkAccess()->isBookmarkDeleted(*this, isReplace))
941 {
942 return true;
943 }
944 }
945 if (!bRet &&
947 {
948 SwPosition const& rStart(*Start());
949 SwPosition const& rEnd(*End());
950 for (SwNodeIndex n(rStart.GetNode()); n <= rEnd.GetNode(); ++n)
951 {
952 if (SwTextNode const*const pNode = n.GetNode().GetTextNode())
953 {
954 if (SwpHints const*const pHints = pNode->GetpSwpHints())
955 {
956 for (size_t i = 0; i < pHints->Count(); ++i)
957 {
958 SwTextAttr const*const pHint(pHints->Get(i));
959 if (n == rStart.GetNode() && pHint->GetStart() < rStart.GetContentIndex())
960 {
961 continue; // before selection
962 }
963 if (n == rEnd.GetNode() && rEnd.GetContentIndex() <= pHint->GetStart())
964 {
965 break; // after selection
966 }
967 if (pHint->Which() == RES_TXTATR_FIELD
968 // placeholders don't work if you can't delete them
970 {
971 return true;
972 }
973 }
974 }
975 }
976 }
977 }
978
979 if (!bRet)
980 {
981 // See if we're inside a read-only content control.
982 const SwPosition* pStart = Start();
983 SwTextNode* pTextNode = pStart->GetNode().GetTextNode();
984 if (pTextNode)
985 {
986 sal_Int32 nIndex = pStart->GetContentIndex();
987 SwTextAttr* pAttr
989 auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
990 if (pTextContentControl)
991 {
992 const SwFormatContentControl& rFormatContentControl
993 = pTextContentControl->GetContentControl();
994 std::shared_ptr<SwContentControl> pContentControl
995 = rFormatContentControl.GetContentControl();
996 if (pContentControl && !pContentControl->GetReadWrite())
997 {
998 switch (pContentControl->GetType())
999 {
1003 bRet = true;
1004 break;
1005 default:
1006 break;
1007 }
1008 }
1009 }
1010 }
1011 }
1012
1013 return bRet;
1014}
1015
1020SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFnCollection const & fnMove,
1021 bool const bInReadOnly, SwRootFrame const*const i_pLayout)
1022{
1023 SwRootFrame const*const pLayout(i_pLayout ? i_pLayout :
1025 SwContentNode * pNd = nullptr;
1026 if( ((*rPam.GetPoint()).*fnMove.fnCmpOp)( *rPam.GetMark() ) ||
1027 ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) )
1028 {
1029 if( rbFirst )
1030 {
1031 rbFirst = false;
1032 pNd = rPam.GetPointContentNode();
1033 if( pNd )
1034 {
1035 SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout));
1036 if(
1037 (
1038 nullptr == pFrame ||
1039 ( !bInReadOnly && pFrame->IsProtected() ) ||
1040 (pFrame->IsTextFrame() && static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow())
1041 ) ||
1042 ( !bInReadOnly && pNd->FindSectionNode() &&
1044 )
1045 )
1046 {
1047 pNd = nullptr;
1048 }
1049 }
1050 }
1051
1052 if( !pNd ) // is the cursor not on a ContentNode?
1053 {
1054 SwPosition aPos( *rPam.GetPoint() );
1055 bool bSrchForward = &fnMove == &fnMoveForward;
1056 SwNodes& rNodes = aPos.GetNodes();
1057
1058 // go to next/previous ContentNode
1059 while( true )
1060 {
1061 if (i_pLayout && aPos.GetNode().IsTextNode())
1062 {
1063 auto const fal(sw::GetFirstAndLastNode(*pLayout, aPos.GetNode()));
1064 aPos.Assign( bSrchForward ? *fal.second : *fal.first );
1065 }
1066
1067 pNd = bSrchForward
1068 ? rNodes.GoNextSection( &aPos, true, !bInReadOnly )
1069 : SwNodes::GoPrevSection( &aPos, true, !bInReadOnly );
1070 if( pNd )
1071 {
1072 if (!bSrchForward)
1073 aPos.AssignEndIndex( *pNd );
1074 // is the position still in the area
1075 if( (aPos.*fnMove.fnCmpOp)( *rPam.GetMark() ) )
1076 {
1077 // only in AutoTextSection can be nodes that are hidden
1078 SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout));
1079 if (nullptr == pFrame ||
1080 ( !bInReadOnly && pFrame->IsProtected() ) ||
1081 ( pFrame->IsTextFrame() &&
1082 static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()))
1083 {
1084 pNd = nullptr;
1085 continue;
1086 }
1087 *rPam.GetPoint() = aPos;
1088 }
1089 else
1090 pNd = nullptr; // no valid node
1091 break;
1092 }
1093 break;
1094 }
1095 }
1096 }
1097 return pNd;
1098}
1099
1101{
1102 SwNodes& rNodes = pPos->GetNodes();
1103 pPos->Assign( *rNodes.GetEndOfContent().StartOfSectionNode() );
1104 // we always need to find a ContentNode!
1105 rNodes.GoNext( pPos );
1106}
1107
1108void GoEndDoc( SwPosition * pPos )
1109{
1110 SwNodes& rNodes = pPos->GetNodes();
1111 pPos->Assign( rNodes.GetEndOfContent() );
1112 SwContentNode* pCNd = GoPreviousPos( pPos, true );
1113 if( pCNd )
1114 pPos->AssignEndIndex(*pCNd);
1115}
1116
1118{
1119 // jump to section's beginning
1120 SwNodes& rNodes = pPos->GetNodes();
1121 sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->GetNode() );
1122 if( pPos->GetNode() < *rNodes.GetEndOfContent().StartOfSectionNode() )
1123 nLevel--;
1124 do { SwNodes::GoStartOfSection( &pPos->nNode ); } while( nLevel-- );
1125
1126 // already on a ContentNode
1127 pPos->AssignStartIndex(*pPos->GetNode().GetContentNode());
1128}
1129
1131{
1132 // jump to section's beginning
1134 pPos->nContent.Assign(pPos->GetNode().GetContentNode(), 0);
1135}
1136
1139{
1140 // jump to section's beginning/end
1141 SwNodes& rNodes = pPos->GetNodes();
1142 sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->GetNode() );
1143 if( pPos->GetNode() < *rNodes.GetEndOfContent().StartOfSectionNode() )
1144 nLevel--;
1145 do { SwNodes::GoEndOfSection( &pPos->nNode ); } while( nLevel-- );
1146
1147 // now on an EndNode, thus to the previous ContentNode
1148 if( SwContentNode* pCNd = GoPreviousNds( &pPos->nNode, true ) )
1149 pPos->AssignEndIndex(*pCNd);
1150}
1151
1153{
1155 SwContentNode* pCNd = pPos->nNode.GetNode().GetContentNode();
1156 pPos->nContent.Assign(pCNd, pCNd ? pCNd->Len() : 0);
1157}
1158
1159bool GoInDoc( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1160{
1161 (*fnMove.fnDoc)( rPam.GetPoint() );
1162 return true;
1163}
1164
1165bool GoInSection( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1166{
1167 (*fnMove.fnSections)( rPam.GetPoint() );
1168 return true;
1169}
1170
1171bool GoInNode( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1172{
1173 SwContentNode *pNd = (*fnMove.fnPos)( rPam.GetPoint(), true );
1174 if( pNd )
1175 rPam.GetPoint()->SetContent(
1176 ::GetSttOrEnd( &fnMove == &fnMoveForward, *pNd ) );
1177 return pNd;
1178}
1179
1180bool GoInContent( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1181{
1182 if( (*fnMove.fnNd)( &rPam.GetPoint()->GetNode(),
1184 return true;
1185 return GoInNode( rPam, fnMove );
1186}
1187
1188bool GoInContentCells( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1189{
1190 if( (*fnMove.fnNd)( &rPam.GetPoint()->GetNode(),
1192 return true;
1193 return GoInNode( rPam, fnMove );
1194}
1195
1196bool GoInContentSkipHidden( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1197{
1198 if( (*fnMove.fnNd)( &rPam.GetPoint()->GetNode(),
1200 return true;
1201 return GoInNode( rPam, fnMove );
1202}
1203
1205{
1206 if( (*fnMove.fnNd)( &rPam.GetPoint()->GetNode(),
1208 return true;
1209 return GoInNode( rPam, fnMove );
1210}
1211
1212bool GoPrevPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara )
1213{
1214 if( rPam.Move( fnMoveBackward, GoInNode ) )
1215 {
1216 // always on a ContentNode
1217 SwPosition& rPos = *rPam.GetPoint();
1218 SwContentNode * pNd = rPos.GetNode().GetContentNode();
1219 rPos.SetContent( ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ) );
1220 return true;
1221 }
1222 return false;
1223}
1224
1225bool GoCurrPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara )
1226{
1227 SwPosition& rPos = *rPam.GetPoint();
1228 SwContentNode * pNd = rPos.GetNode().GetContentNode();
1229 if( pNd )
1230 {
1231 const sal_Int32 nOld = rPos.GetContentIndex();
1232 const sal_Int32 nNew = &aPosPara == &fnMoveForward ? 0 : pNd->Len();
1233 // if already at beginning/end then to the next/previous
1234 if( nOld != nNew )
1235 {
1236 rPos.SetContent( nNew );
1237 return true;
1238 }
1239 }
1240 // move node to next/previous ContentNode
1241 if( ( &aPosPara==&fnParaStart && nullptr != ( pNd =
1242 GoPreviousPos( &rPos, true ))) ||
1243 ( &aPosPara==&fnParaEnd && nullptr != ( pNd =
1244 GoNextPos( &rPos, true ))) )
1245 {
1246 rPos.SetContent( ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ));
1247 return true;
1248 }
1249 return false;
1250}
1251
1252bool GoNextPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara )
1253{
1254 if( rPam.Move( fnMoveForward, GoInNode ) )
1255 {
1256 // always on a ContentNode
1257 SwPosition& rPos = *rPam.GetPoint();
1258 SwContentNode * pNd = rPos.GetNode().GetContentNode();
1259 rPos.SetContent( ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ) );
1260 return true;
1261 }
1262 return false;
1263}
1264
1265bool GoCurrSection( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1266{
1267 SwPosition& rPos = *rPam.GetPoint();
1268 SwPosition aSavePos( rPos ); // position for comparison
1269 (fnMove.fnSection)( &rPos );
1270 SwContentNode *pNd;
1271 if( nullptr == ( pNd = rPos.GetNode().GetContentNode()) &&
1272 nullptr == ( pNd = (*fnMove.fnPos)( &rPos, true )) )
1273 {
1274 rPos = aSavePos; // do not change cursor
1275 return false;
1276 }
1277
1278 rPos.SetContent( ::GetSttOrEnd( &fnMove == &fnMoveForward, *pNd ) );
1279 return aSavePos != rPos;
1280}
1281
1282OUString SwPaM::GetText() const
1283{
1284 OUStringBuffer aResult;
1285
1286 SwNodeIndex aNodeIndex = Start()->nNode;
1287
1288 // The first node can be already the end node.
1289 // Use a "forever" loop with an exit condition in the middle
1290 // of its body, in order to correctly handle all cases.
1291 bool bIsStartNode = true;
1292 for (;;)
1293 {
1294 const bool bIsEndNode = aNodeIndex == End()->nNode;
1295 SwTextNode * pTextNode = aNodeIndex.GetNode().GetTextNode();
1296
1297 if (pTextNode != nullptr)
1298 {
1299 if (!bIsStartNode)
1300 {
1301 aResult.append(CH_TXTATR_NEWLINE); // use newline for para break
1302 }
1303 const OUString& aTmpStr = pTextNode->GetText();
1304
1305 if (bIsStartNode || bIsEndNode)
1306 {
1307 // Handle corner cases of start/end node(s)
1308 const sal_Int32 nStart = bIsStartNode
1309 ? Start()->GetContentIndex()
1310 : 0;
1311 const sal_Int32 nEnd = bIsEndNode
1312 ? End()->GetContentIndex()
1313 : aTmpStr.getLength();
1314
1315 aResult.append(aTmpStr.subView(nStart, nEnd-nStart));
1316 }
1317 else
1318 {
1319 aResult.append(aTmpStr);
1320 }
1321 }
1322
1323 if (bIsEndNode)
1324 {
1325 break;
1326 }
1327
1328 ++aNodeIndex;
1329 bIsStartNode = false;
1330 }
1331
1332 return aResult.makeStringAndClear();
1333}
1334
1336{
1337 for (SwNodeIndex index(Start()->GetNode()); index <= End()->GetNode(); ++index)
1338 {
1339 if (SwTextNode *const pTextNode = index.GetNode().GetTextNode())
1340 {
1341 // pretend that the PaM marks changed formatting to reformat...
1342 sal_Int32 const nStart(
1343 index == Start()->nNode ? Start()->GetContentIndex() : 0);
1344 // this should work even for length of 0
1345 SwUpdateAttr const aHint(
1346 nStart,
1347 index == End()->nNode
1348 ? End()->GetContentIndex() - nStart
1349 : pTextNode->Len() - nStart,
1350 0);
1351 pTextNode->TriggerNodeUpdate(sw::LegacyModifyHint(&aHint, &aHint));
1352 }
1353 // other node types not invalidated
1354 }
1355}
1356
1358{
1359 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwPaM"));
1360
1361 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("point"));
1362 GetPoint()->dumpAsXml(pWriter);
1363 (void)xmlTextWriterEndElement(pWriter);
1364
1365 if (HasMark())
1366 {
1367 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mark"));
1368 GetMark()->dumpAsXml(pWriter);
1369 (void)xmlTextWriterEndElement(pWriter);
1370 }
1371
1372 (void)xmlTextWriterEndElement(pWriter);
1373}
1374
1375std::ostream &operator <<(std::ostream& s, const SwPaM& pam)
1376{
1377 if( pam.HasMark())
1378 return s << "SwPaM (point " << *pam.GetPoint() << ", mark " << *pam.GetMark() << ")";
1379 else
1380 return s << "SwPaM (point " << *pam.GetPoint() << ")";
1381}
1382
1383
1384/* 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 ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &pos) const =0
virtual bool isBookmarkDeleted(SwPaM const &rPaM, bool isReplace) const =0
check if the selection would delete a BOOKMARK
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
Marks a character position inside a document model content node (SwContentNode)
const SwContentNode * GetContentNode() const
SwContentIndex & Assign(const SwContentNode *, sal_Int32)
Definition: index.cxx:206
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1230
virtual sal_Int32 Len() const
Definition: node.cxx:1263
Definition: doc.hxx:195
SwSectionFormats & GetSections()
Definition: doc.hxx:1348
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:330
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:413
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:184
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1872
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:194
SwFieldIds Which() const
Definition: fldbas.hxx:274
SwFieldType * GetTyp() const
Definition: fldbas.hxx:399
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
SfxPoolItem subclass that wraps an SwContentControl.
const std::shared_ptr< SwContentControl > & GetContentControl() const
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:130
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:1639
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
const SwFrame * Lower() const
Definition: layfrm.hxx:101
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNodeIndex & Assign(SwNodes const &rNds, SwNodeOffset)
Definition: ndindex.hxx:291
const SwNodes & GetNodes() const
Definition: ndindex.hxx:175
SwNode & GetNode() const
Definition: ndindex.hxx:136
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:171
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:897
SwSectionNode * GetSectionNode()
Definition: node.hxx:658
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:744
bool IsContentNode() const
Definition: node.hxx:679
SwDoc & GetDoc()
Definition: node.hxx:233
bool IsStartNode() const
Definition: node.hxx:675
SwNodeOffset StartOfSectionIndex() const
Definition: node.hxx:724
bool IsTextNode() const
Definition: node.hxx:687
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:974
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:728
SwContentNode * GetContentNode()
Definition: node.hxx:666
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:733
static sal_uInt16 GetSectionLevel(const SwNode &rIndex)
get section level at the given position
Definition: nodes.cxx:1267
static void GoEndOfSection(SwNodeIndex *)
Definition: nodes.cxx:1293
SwNode & GetEndOfAutotext() const
Section for all Flys/Header/Footers.
Definition: ndarr.hxx:158
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc....
Definition: nodes.cxx:2543
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1333
static void GoStartOfSection(SwNodeIndex *)
Definition: nodes.cxx:1275
SwNode & GetEndOfRedlines() const
Section for all Redlines.
Definition: ndarr.hxx:160
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1299
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:1948
SwNode & GetEndOfInserts() const
Section for all footnotes.
Definition: ndarr.hxx:156
SwNode & GetEndOfPostIts() const
A still empty section.
Definition: ndarr.hxx:154
static SwContentNode * GoPrevSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true)
Definition: nodes.cxx:2064
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
const SwPosition * GetMark() const
Definition: pam.hxx:263
SwPaM & operator=(const SwPaM &)
@@ semantic: no copy assignment for super class Ring.
Definition: pam.cxx:624
SwPosition m_Bound1
Definition: pam.hxx:188
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: pam.cxx:1357
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:642
void Exchange()
Definition: pam.cxx:656
SwPosition * m_pMark
points at either m_Bound1 or m_Bound2
Definition: pam.hxx:191
virtual ~SwPaM() override
Definition: pam.cxx:612
void Normalize(bool bPointFirst=true)
Normalizes PaM, i.e.
Definition: pam.cxx:700
SwPosition * m_pPoint
points at either m_Bound1 or m_Bound2
Definition: pam.hxx:190
SwContentNode * GetPointContentNode() const
Definition: pam.hxx:287
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:668
const SwPosition * End() const
Definition: pam.hxx:271
SwPaM(SwPaM const &rPaM)=delete
SwDoc & GetDoc() const
Definition: pam.hxx:299
SwPosition m_Bound2
Definition: pam.hxx:189
sal_uInt16 GetPageNum(bool bAtPoint=true, const Point *pLayPos=nullptr)
Get number of page which contains cursor.
Definition: pam.cxx:711
OUString GetText() const
Definition: pam.cxx:1282
bool m_bIsInFrontOfLabel
Definition: pam.hxx:192
void DeleteMark()
Definition: pam.hxx:231
bool HasReadonlySel(bool bFormView, bool isReplace) const
Is in something protected (readonly) or selection contains something protected.
Definition: pam.cxx:757
const SwPosition * GetPoint() const
Definition: pam.hxx:261
const SwPosition * Start() const
Definition: pam.hxx:266
void InvalidatePaM()
Definition: pam.cxx:1335
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:259
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:83
Array of Undo-history.
Definition: docary.hxx:192
SwSection * GetSection()
Definition: sectfrm.hxx:97
A section node represents the start of a section on the UI, i.e.
Definition: node.hxx:575
const SwSection & GetSection() const
Definition: node.hxx:590
bool IsProtectFlag() const
Definition: section.hxx:191
bool IsProtect() const
Definition: section.cxx:334
bool IsEditInReadonlyFlag() const
Definition: section.hxx:192
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:165
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1360
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:111
SwTextAttr * GetTextAttrAt(sal_Int32 const nIndex, sal_uInt16 const nWhich, ::sw::GetTextAttrMode const eMode=::sw::GetTextAttrMode::Default) const
get the innermost text attribute covering position nIndex.
Definition: ndtxt.cxx:1802
const OUString & GetText() const
Definition: ndtxt.hxx:242
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.
static SwContentNode * GetContentNode(SwDoc &rDoc, SwPosition &rPos, bool bNext)
Definition: fltshell.cxx:54
constexpr TypedWhichId< SwFormatContentControl > RES_TXTATR_CONTENTCONTROL(56)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
#define CH_TXTATR_NEWLINE
Definition: hintids.hxx:174
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.
void MakeRegion(SwMoveFnCollection const &fnMove, const SwPaM &rOrigRg, std::optional< SwPaM > &rPam)
make a new region
Definition: pam.cxx:687
std::pair< SwTextNode *, SwTextNode * > GetFirstAndLastNode(SwRootFrame const &rLayout, SwNode const &rPos)
Definition: txtfrm.cxx:354
@ Parent
EXPAND : (Start < nIndex <= End)
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
constexpr OUStringLiteral ODF_UNHANDLED
void GoEndOfSection(SwPosition *pPos)
Definition: pam.cxx:1152
bool GoCurrPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1225
SwContentNode * GoNextNds(SwNodeIndex *pIdx, bool bChk)
Definition: pam.cxx:394
bool GoInContentSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1196
bool GoPrevPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1212
SwContentNode * GoPreviousPos(SwPosition *pIdx, bool bChk)
Definition: pam.cxx:439
void GoStartSection(SwPosition *pPos)
Definition: pam.cxx:1117
bool GoInContentCells(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1188
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1171
std::ostream & operator<<(std::ostream &s, const SwPosition &position)
Definition: pam.cxx:283
void GoStartDoc(SwPosition *pPos)
Definition: pam.cxx:1100
bool GoNext(SwNode *pNd, SwContentIndex *pIdx, SwCursorSkipMode nMode)
Definition: pam.cxx:380
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:1020
bool GoInDoc(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1159
void GoStartOfSection(SwPosition *pPos)
Definition: pam.cxx:1130
bool GoInContentCellsSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1204
static CHKSECTION lcl_TstIdx(SwNodeOffset nSttIdx, SwNodeOffset nEndIdx, const SwNode &rEndNd)
Definition: pam.cxx:294
bool CheckNodesRange(const SwNode &rStt, const SwNode &rEnd, bool bChkSection)
Check if the given range is inside one of the defined top-level sections.
Definition: pam.cxx:348
static const SwFrame * lcl_FindEditInReadonlyFrame(const SwFrame &rFrame)
Definition: pam.cxx:732
SwContentNode * GoPreviousNds(SwNodeIndex *pIdx, bool bChk)
Definition: pam.cxx:409
bool GoPrevious(SwNode *pNd, SwContentIndex *pIdx, SwCursorSkipMode nMode)
Definition: pam.cxx:387
void GoEndDoc(SwPosition *pPos)
Definition: pam.cxx:1108
bool GoNextPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1252
bool GoInSection(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1165
void GoEndSection(SwPosition *pPos)
go to the end of the current base section
Definition: pam.cxx:1138
static bool lcl_ChkOneRange(CHKSECTION eSec, bool bChkSections, const SwNode &rBaseEnd, SwNodeOffset nStt, SwNodeOffset nEnd)
Definition: pam.cxx:303
static sal_Int32 GetSttOrEnd(bool bCondition, const SwContentNode &rNd)
Definition: pam.cxx:56
SwContentNode * GoNextPos(SwPosition *pIdx, bool bChk)
Definition: pam.cxx:424
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1180
bool GoCurrSection(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1265
auto(*)(SwPaM &rPam, SwMoveFnCollection const &fnMove) -> bool SwGoInDoc
Definition: pam.hxx:171
SwMoveFnCollection const & fnParaStart
Definition: paminit.cxx:48
SwMoveFnCollection const & fnParaEnd
Definition: paminit.cxx:49
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:60
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:61
MvSection fnSection
Definition: pamtyp.hxx:86
GoSection fnSections
Definition: pamtyp.hxx:82
Marks a position in the document model.
Definition: pam.hxx:37
void Adjust(SwNodeOffset nDelta)
Adjust node position, and resets content position to zero.
Definition: pam.cxx:256
SwNode & GetNode() const
Definition: pam.hxx:80
bool operator<(const SwPosition &) const
Definition: pam.cxx:121
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:230
void AssignEndIndex(const SwContentNode &rNd)
Set nNode to rNd, and nContent to the end of rNd.
Definition: pam.cxx:276
void SetContent(sal_Int32 nContentIndex)
Set content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:266
SwNodeIndex nNode
Definition: pam.hxx:38
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: pam.cxx:222
bool operator>(const SwPosition &) const
Definition: pam.cxx:142
bool operator>=(const SwPosition &) const
Definition: pam.cxx:184
const SwContentNode * GetContentNode() const
Definition: pam.hxx:83
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:77
bool operator<=(const SwPosition &) const
Definition: pam.cxx:163
const SwNodes & GetNodes() const
Definition: pam.hxx:78
void AssignStartIndex(const SwContentNode &rNd)
Set nNode to rNd, and nContent to the beginning of rNd.
Definition: pam.cxx:271
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
SwPosition(const SwNodeIndex &rNode, const SwContentIndex &rContent)
Definition: pam.cxx:61
bool operator==(const SwPosition &) const
Definition: pam.cxx:205
void AdjustContent(sal_Int32 nDelta)
Adjust content index, only valid to call this if the position points to a SwContentNode subclass.
Definition: pam.cxx:261
SwDoc & GetDoc() const
Returns the document this position is in.
Definition: pam.cxx:217
bool operator!=(const SwPosition &) const
Definition: pam.cxx:211
SwContentIndex nContent
Definition: pam.hxx:39
SwCursorSkipMode
Definition: swcrsr.hxx:65