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
424SwPaM::SwPaM( const SwPosition& rPos, SwPaM* pRing )
425 : Ring( pRing )
426 , m_Bound1( rPos )
427 , m_Bound2( rPos.GetNode().GetNodes() ) // default initialize
428 , m_pPoint( &m_Bound1 )
429 , m_pMark( m_pPoint )
430 , m_bIsInFrontOfLabel( false )
431{
432}
433
434SwPaM::SwPaM( const SwPosition& rMark, const SwPosition& rPoint, SwPaM* pRing )
435 : Ring( pRing )
436 , m_Bound1( rMark )
437 , m_Bound2( rPoint )
438 , m_pPoint( &m_Bound2 )
439 , m_pMark( &m_Bound1 )
440 , m_bIsInFrontOfLabel( false )
441{
442}
443
444SwPaM::SwPaM( const SwNodeIndex& rMark, const SwNodeIndex& rPoint,
445 SwNodeOffset nMarkOffset, SwNodeOffset nPointOffset, SwPaM* pRing )
446 : Ring( pRing )
447 , m_Bound1( rMark )
448 , m_Bound2( rPoint )
449 , m_pPoint( &m_Bound2 )
450 , m_pMark( &m_Bound1 )
451 , m_bIsInFrontOfLabel( false )
452{
453 if ( nMarkOffset )
454 {
455 m_pMark->nNode += nMarkOffset;
456 }
457 if ( nPointOffset )
458 {
459 m_pPoint->nNode += nPointOffset;
460 }
463}
464
465SwPaM::SwPaM( const SwNode& rMark, const SwNode& rPoint,
466 SwNodeOffset nMarkOffset, SwNodeOffset nPointOffset, SwPaM* pRing )
467 : Ring( pRing )
468 , m_Bound1( rMark )
469 , m_Bound2( rPoint )
470 , m_pPoint( &m_Bound2 )
471 , m_pMark( &m_Bound1 )
472 , m_bIsInFrontOfLabel( false )
473{
474 if ( nMarkOffset )
475 {
476 m_pMark->nNode += nMarkOffset;
477 }
478 if ( nPointOffset )
479 {
480 m_pPoint->nNode += nPointOffset;
481 }
484}
485
486SwPaM::SwPaM( const SwNodeIndex& rMark, sal_Int32 nMarkContent,
487 const SwNodeIndex& rPoint, sal_Int32 nPointContent, SwPaM* pRing )
488 : Ring( pRing )
489 , m_Bound1( rMark )
490 , m_Bound2( rPoint )
491 , m_pPoint( &m_Bound2 )
492 , m_pMark( &m_Bound1 )
493 , m_bIsInFrontOfLabel( false )
494{
495 m_pPoint->nContent.Assign( rPoint.GetNode().GetContentNode(), nPointContent);
496 m_pMark ->nContent.Assign( rMark .GetNode().GetContentNode(), nMarkContent );
497}
498
499SwPaM::SwPaM( const SwNode& rMark, sal_Int32 nMarkContent,
500 const SwNode& rPoint, sal_Int32 nPointContent, SwPaM* pRing )
501 : Ring( pRing )
502 , m_Bound1( rMark )
503 , m_Bound2( rPoint )
504 , m_pPoint( &m_Bound2 )
505 , m_pMark( &m_Bound1 )
506 , m_bIsInFrontOfLabel( false )
507{
509 nPointContent);
511 nMarkContent );
512}
513
514SwPaM::SwPaM( const SwNode& rMark, SwNodeOffset nMarkOffset, sal_Int32 nMarkContent,
515 const SwNode& rPoint, SwNodeOffset nPointOffset, sal_Int32 nPointContent, SwPaM* pRing )
516 : Ring( pRing )
517 , m_Bound1( rMark )
518 , m_Bound2( rPoint )
519 , m_pPoint( &m_Bound2 )
520 , m_pMark( &m_Bound1 )
521 , m_bIsInFrontOfLabel( false )
522{
523 if ( nMarkOffset )
524 {
525 m_pMark->nNode += nMarkOffset;
526 }
527 if ( nPointOffset )
528 {
529 m_pPoint->nNode += nPointOffset;
530 }
532 nPointContent);
534 nMarkContent );
535}
536
537SwPaM::SwPaM( const SwNode& rNode, sal_Int32 nContent, SwPaM* pRing )
538 : Ring( pRing )
539 , m_Bound1( rNode )
540 , m_Bound2( m_Bound1.GetNode().GetNodes() ) // default initialize
541 , m_pPoint( &m_Bound1 )
542 , m_pMark( &m_Bound1 )
543 , m_bIsInFrontOfLabel( false )
544{
546 nContent );
547}
548
549SwPaM::SwPaM( const SwNode& rNode, SwNodeOffset nNdOffset, sal_Int32 nContent, SwPaM* pRing )
550 : Ring( pRing )
551 , m_Bound1( rNode, nNdOffset )
552 , m_Bound2( m_Bound1.GetNode().GetNodes() ) // default initialize
553 , m_pPoint( &m_Bound1 )
554 , m_pMark( &m_Bound1 )
555 , m_bIsInFrontOfLabel( false )
556{
558 nContent );
559}
560
561SwPaM::SwPaM( const SwNodeIndex& rNodeIdx, sal_Int32 nContent, SwPaM* pRing )
562 : Ring( pRing )
563 , m_Bound1( rNodeIdx )
564 , m_Bound2( rNodeIdx.GetNode().GetNodes() ) // default initialize
565 , m_pPoint( &m_Bound1 )
566 , m_pMark( &m_Bound1 )
567 , m_bIsInFrontOfLabel( false )
568{
569 m_pPoint->nContent.Assign( rNodeIdx.GetNode().GetContentNode(), nContent );
570}
571
572SwPaM::SwPaM( SwNodes& rNodes, SwNodeOffset nNdOffset, SwPaM* pRing )
573 : Ring( pRing )
574 , m_Bound1( rNodes, nNdOffset )
575 , m_Bound2( rNodes ) // default initialize
576 , m_pPoint( &m_Bound1 )
577 , m_pMark( &m_Bound1 )
578 , m_bIsInFrontOfLabel( false )
579{
580}
581
583
584SwPaM::SwPaM(SwPaM const& rPam, SwPaM *const pRing)
585 : Ring(pRing)
586 , m_Bound1( *(rPam.m_pPoint) )
587 , m_Bound2( *(rPam.m_pMark) )
588 , m_pPoint( &m_Bound1 ), m_pMark( rPam.HasMark() ? &m_Bound2 : m_pPoint )
589 , m_bIsInFrontOfLabel( false )
590{
591}
592
593// @@@ semantic: no copy assignment for super class Ring.
595{
596 if(this == &rPam)
597 return *this;
598
599 *m_pPoint = *( rPam.m_pPoint );
600 if ( rPam.HasMark() )
601 {
602 SetMark();
603 *m_pMark = *( rPam.m_pMark );
604 }
605 else
606 {
607 DeleteMark();
608 }
609 return *this;
610}
611
613{
614 if (m_pPoint == &m_Bound1)
615 {
616 m_pMark = &m_Bound2;
617 }
618 else
619 {
620 m_pMark = &m_Bound1;
621 }
622 (*m_pMark) = *m_pPoint;
623}
624
625#ifdef DBG_UTIL
627{
628 if (m_pPoint != m_pMark)
629 {
630 SwPosition *pTmp = m_pPoint;
632 m_pMark = pTmp;
633 }
634}
635#endif
636
638bool SwPaM::Move( SwMoveFnCollection const & fnMove, SwGoInDoc fnGo )
639{
640 const bool bRet = (*fnGo)( *this, fnMove );
641
642 m_bIsInFrontOfLabel = false;
643 return bRet;
644}
645
646namespace sw {
647
657void MakeRegion(SwMoveFnCollection const & fnMove,
658 const SwPaM & rOrigRg, std::optional<SwPaM>& rPam)
659{
660 rPam.emplace(rOrigRg, const_cast<SwPaM*>(&rOrigRg)); // given search range
661 // make sure that SPoint is on the "real" start position
662 // FORWARD: SPoint always smaller than GetMark
663 // BACKWARD: SPoint always bigger than GetMark
664 if( (rPam->GetMark()->*fnMove.fnCmpOp)( *rPam->GetPoint() ) )
665 rPam->Exchange();
666}
667
668} // namespace sw
669
670void SwPaM::Normalize(bool bPointFirst)
671{
672 if (HasMark())
673 if ( ( bPointFirst && *m_pPoint > *m_pMark) ||
674 (!bPointFirst && *m_pPoint < *m_pMark) )
675 {
676 Exchange();
677 }
678}
679
681sal_uInt16 SwPaM::GetPageNum( bool bAtPoint, const Point* pLayPos )
682{
683 const SwContentFrame* pCFrame;
684 const SwPageFrame *pPg;
685 const SwContentNode *pNd ;
686 const SwPosition* pPos = bAtPoint ? m_pPoint : m_pMark;
687
688 std::pair<Point, bool> tmp;
689 if (pLayPos)
690 {
691 tmp.first = *pLayPos;
692 tmp.second = false;
693 }
694 if( nullptr != ( pNd = pPos->GetNode().GetContentNode() ) &&
695 nullptr != (pCFrame = pNd->getLayoutFrame(pNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), pPos, pLayPos ? &tmp : nullptr)) &&
696 nullptr != ( pPg = pCFrame->FindPageFrame() ))
697 return pPg->GetPhyPageNum();
698 return 0;
699}
700
701// form view - see also SwCursorShell::IsCursorReadonly()
702static const SwFrame* lcl_FindEditInReadonlyFrame( const SwFrame& rFrame )
703{
704 const SwFrame* pRet = nullptr;
705
706 const SwFlyFrame* pFly;
707 const SwSectionFrame* pSectionFrame;
708
709 if( rFrame.IsInFly() &&
710 (pFly = rFrame.FindFlyFrame())->GetFormat()->GetEditInReadonly().GetValue() &&
711 pFly->Lower() &&
712 !pFly->Lower()->IsNoTextFrame() )
713 {
714 pRet = pFly;
715 }
716 else if ( rFrame.IsInSct() &&
717 nullptr != ( pSectionFrame = rFrame.FindSctFrame() )->GetSection() &&
718 pSectionFrame->GetSection()->IsEditInReadonlyFlag() )
719 {
720 pRet = pSectionFrame;
721 }
722
723 return pRet;
724}
725
727bool SwPaM::HasReadonlySel(bool bFormView, bool const isReplace) const
728{
729 bool bRet = false;
730
731 const SwContentNode* pNd = GetPoint()->GetNode().GetContentNode();
732 const SwContentFrame *pFrame = nullptr;
733 if ( pNd != nullptr )
734 {
735 Point aTmpPt;
736 std::pair<Point, bool> const tmp(aTmpPt, false);
737 pFrame = pNd->getLayoutFrame(
739 GetPoint(), &tmp);
740 }
741
742 // Will be set if point are inside edit-in-readonly environment
743 const SwFrame* pPointEditInReadonlyFrame = nullptr;
744 if ( pFrame != nullptr
745 && ( pFrame->IsProtected()
746 || ( bFormView
747 && nullptr == ( pPointEditInReadonlyFrame = lcl_FindEditInReadonlyFrame( *pFrame ) ) ) ) )
748 {
749 bRet = true;
750 }
751 else if( pNd != nullptr )
752 {
753 const SwSectionNode* pSNd = pNd->GetSectionNode();
754 if ( pSNd != nullptr
755 && ( pSNd->GetSection().IsProtectFlag()
756 || ( bFormView
757 && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
758 {
759 bRet = true;
760 }
761 else
762 {
763 const SwSectionNode* pParentSectionNd = pNd->FindSectionNode();
764 if ( pParentSectionNd != nullptr
765 && ( pParentSectionNd->GetSection().IsProtectFlag()
766 || ( bFormView && !pParentSectionNd->GetSection().IsEditInReadonlyFlag()) ) )
767 {
768 bRet = true;
769 }
770 }
771 }
772
773 if ( !bRet
774 && HasMark()
775 && GetPoint()->nNode != GetMark()->nNode )
776 {
777 pNd = GetMark()->GetNode().GetContentNode();
778 pFrame = nullptr;
779 if ( pNd != nullptr )
780 {
781 Point aTmpPt;
782 std::pair<Point, bool> const tmp(aTmpPt, false);
783 pFrame = pNd->getLayoutFrame(
785 GetMark(), &tmp);
786 }
787
788 const SwFrame* pMarkEditInReadonlyFrame = nullptr;
789 if ( pFrame != nullptr
790 && ( pFrame->IsProtected()
791 || ( bFormView
792 && nullptr == ( pMarkEditInReadonlyFrame = lcl_FindEditInReadonlyFrame( *pFrame ) ) ) ) )
793 {
794 bRet = true;
795 }
796 else if( pNd != nullptr )
797 {
798 const SwSectionNode* pSNd = pNd->GetSectionNode();
799 if ( pSNd != nullptr
800 && ( pSNd->GetSection().IsProtectFlag()
801 || ( bFormView
802 && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
803 {
804 bRet = true;
805 }
806 }
807
808 if ( !bRet && bFormView )
809 {
810 // Check if start and end frame are inside the _same_
811 // edit-in-readonly-environment. Otherwise we better return 'true'
812 if ( pPointEditInReadonlyFrame != pMarkEditInReadonlyFrame )
813 bRet = true;
814 }
815
816 // check for protected section inside the selection
817 if( !bRet )
818 {
819 SwNodeOffset nSttIdx = GetMark()->GetNodeIndex(),
820 nEndIdx = GetPoint()->GetNodeIndex();
821 if( nEndIdx < nSttIdx )
822 std::swap( nSttIdx, nEndIdx );
823
824 // If a protected section should be between nodes, then the
825 // selection needs to contain already x nodes.
826 // (TextNd, SectNd, TextNd, EndNd, TextNd )
827 if( nSttIdx + SwNodeOffset(3) < nEndIdx )
828 {
829 const SwSectionFormats& rFormats = GetDoc().GetSections();
830 for( SwSectionFormats::size_type n = rFormats.size(); n; )
831 {
832 const SwSectionFormat* pFormat = rFormats[ --n ];
833 if( pFormat->GetProtect().IsContentProtected() )
834 {
835 const SwFormatContent& rContent = pFormat->GetContent(false);
836 OSL_ENSURE( rContent.GetContentIdx(), "where is the SectionNode?" );
837 SwNodeOffset nIdx = rContent.GetContentIdx()->GetIndex();
838 if( nSttIdx <= nIdx && nEndIdx >= nIdx &&
839 rContent.GetContentIdx()->GetNode().GetNodes().IsDocNodes() )
840 {
841 bRet = true;
842 break;
843 }
844 }
845 }
846 }
847 }
848 }
849
850 const SwDoc& rDoc = GetDoc();
851 // Legacy text/combo/checkbox: never return read-only when inside these form fields.
852 const IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess();
853 sw::mark::IFieldmark* pA = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : nullptr;
854 sw::mark::IFieldmark* pB = GetMark() ? pMarksAccess->getFieldmarkFor( *GetMark( ) ) : pA;
855 // prevent the user from accidentally deleting the field itself when modifying the text.
856 const bool bAtStartA = (pA != nullptr) && (pA->GetMarkStart() == *GetPoint());
857 const bool bAtStartB = (pB != nullptr) && (pB->GetMarkStart() == *GetMark());
858
860 {
861 ; // allow editing all fields in generic mode
862 }
863 else if (!bRet)
864 {
865 bool bUnhandledMark = pA && pA->GetFieldname( ) == ODF_UNHANDLED;
866 // Unhandled fieldmarks case shouldn't be edited manually to avoid breaking anything
867 if ( ( pA == pB ) && bUnhandledMark )
868 bRet = true;
869 else
870 {
871 if ((pA == pB) && (bAtStartA != bAtStartB))
872 bRet = true;
873 else if (pA != pB)
874 {
875 // If both points are either outside or at marks edges (i.e. selection either
876 // touches fields, or fully encloses it), then don't disable editing
877 bRet = !( ( !pA || bAtStartA ) && ( !pB || bAtStartB ) );
878 }
879 if( !bRet && rDoc.GetDocumentSettingManager().get( DocumentSettingId::PROTECT_FORM ) && (pA || pB) )
880 {
881 // Form protection case
882 bRet = ( pA == nullptr ) || ( pB == nullptr ) || bAtStartA || bAtStartB;
883 }
884 }
885 }
886 else
887 {
888 // Allow editing when the cursor/selection is fully inside of a legacy form field.
889 bRet = !( pA != nullptr && !bAtStartA && !bAtStartB && pA == pB );
890 }
891
892 if (!bRet)
893 {
894 // Paragraph Signatures and Classification fields are read-only.
895 if (rDoc.GetEditShell())
897 }
898
899 if (!bRet &&
901 {
902 if (rDoc.getIDocumentMarkAccess()->isBookmarkDeleted(*this, isReplace))
903 {
904 return true;
905 }
906 }
907 if (!bRet &&
909 {
910 SwPosition const& rStart(*Start());
911 SwPosition const& rEnd(*End());
912 for (SwNodeIndex n(rStart.GetNode()); n <= rEnd.GetNode(); ++n)
913 {
914 if (SwTextNode const*const pNode = n.GetNode().GetTextNode())
915 {
916 if (SwpHints const*const pHints = pNode->GetpSwpHints())
917 {
918 for (size_t i = 0; i < pHints->Count(); ++i)
919 {
920 SwTextAttr const*const pHint(pHints->Get(i));
921 if (n == rStart.GetNode() && pHint->GetStart() < rStart.GetContentIndex())
922 {
923 continue; // before selection
924 }
925 if (n == rEnd.GetNode() && rEnd.GetContentIndex() <= pHint->GetStart())
926 {
927 break; // after selection
928 }
929 if (pHint->Which() == RES_TXTATR_FIELD
930 // placeholders don't work if you can't delete them
932 {
933 return true;
934 }
935 }
936 }
937 }
938 }
939 }
940
941 if (!bRet)
942 {
943 // See if we're inside a read-only content control.
944 const SwPosition* pStart = Start();
945 SwTextNode* pTextNode = pStart->GetNode().GetTextNode();
946 if (pTextNode)
947 {
948 sal_Int32 nIndex = pStart->GetContentIndex();
949 SwTextAttr* pAttr
951 auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
952 if (pTextContentControl)
953 {
954 const SwFormatContentControl& rFormatContentControl
955 = pTextContentControl->GetContentControl();
956 std::shared_ptr<SwContentControl> pContentControl
957 = rFormatContentControl.GetContentControl();
958 if (pContentControl && !pContentControl->GetReadWrite())
959 {
960 switch (pContentControl->GetType())
961 {
965 bRet = true;
966 break;
967 default:
968 break;
969 }
970 }
971 }
972 }
973 }
974
975 return bRet;
976}
977
982SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFnCollection const & fnMove,
983 bool const bInReadOnly, SwRootFrame const*const i_pLayout)
984{
985 SwRootFrame const*const pLayout(i_pLayout ? i_pLayout :
987 SwContentNode * pNd = nullptr;
988 if( ((*rPam.GetPoint()).*fnMove.fnCmpOp)( *rPam.GetMark() ) ||
989 ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) )
990 {
991 if( rbFirst )
992 {
993 rbFirst = false;
994 pNd = rPam.GetPointContentNode();
995 if( pNd )
996 {
997 SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout));
998 if(
999 (
1000 nullptr == pFrame ||
1001 ( !bInReadOnly && pFrame->IsProtected() ) ||
1002 (pFrame->IsTextFrame() && static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow())
1003 ) ||
1004 ( !bInReadOnly && pNd->FindSectionNode() &&
1006 )
1007 )
1008 {
1009 pNd = nullptr;
1010 }
1011 }
1012 }
1013
1014 if( !pNd ) // is the cursor not on a ContentNode?
1015 {
1016 SwPosition aPos( *rPam.GetPoint() );
1017 bool bSrchForward = &fnMove == &fnMoveForward;
1018 SwNodes& rNodes = aPos.GetNodes();
1019
1020 // go to next/previous ContentNode
1021 while( true )
1022 {
1023 if (i_pLayout && aPos.GetNode().IsTextNode())
1024 {
1025 auto const fal(sw::GetFirstAndLastNode(*pLayout, aPos.GetNode()));
1026 aPos.nNode = bSrchForward ? *fal.second : *fal.first;
1027 }
1028
1029 pNd = bSrchForward
1030 ? rNodes.GoNextSection( &aPos, true, !bInReadOnly )
1031 : SwNodes::GoPrevSection( &aPos, true, !bInReadOnly );
1032 if( pNd )
1033 {
1034 if (!bSrchForward)
1035 aPos.AssignEndIndex( *pNd );
1036 // is the position still in the area
1037 if( (aPos.*fnMove.fnCmpOp)( *rPam.GetMark() ) )
1038 {
1039 // only in AutoTextSection can be nodes that are hidden
1040 SwContentFrame const*const pFrame(pNd->getLayoutFrame(pLayout));
1041 if (nullptr == pFrame ||
1042 ( !bInReadOnly && pFrame->IsProtected() ) ||
1043 ( pFrame->IsTextFrame() &&
1044 static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()))
1045 {
1046 pNd = nullptr;
1047 continue;
1048 }
1049 *rPam.GetPoint() = aPos;
1050 }
1051 else
1052 pNd = nullptr; // no valid node
1053 break;
1054 }
1055 break;
1056 }
1057 }
1058 }
1059 return pNd;
1060}
1061
1063{
1064 SwNodes& rNodes = pPos->GetNodes();
1065 pPos->nNode = *rNodes.GetEndOfContent().StartOfSectionNode();
1066 // we always need to find a ContentNode!
1067 rNodes.GoNext( pPos );
1068}
1069
1070void GoEndDoc( SwPosition * pPos )
1071{
1072 SwNodes& rNodes = pPos->GetNodes();
1073 pPos->nNode = rNodes.GetEndOfContent();
1074 SwContentNode* pCNd = GoPreviousNds( &pPos->nNode, true );
1075 if( pCNd )
1076 pPos->AssignEndIndex(*pCNd);
1077}
1078
1080{
1081 // jump to section's beginning
1082 SwNodes& rNodes = pPos->GetNodes();
1083 sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->GetNode() );
1084 if( pPos->GetNode() < *rNodes.GetEndOfContent().StartOfSectionNode() )
1085 nLevel--;
1086 do { SwNodes::GoStartOfSection( &pPos->nNode ); } while( nLevel-- );
1087
1088 // already on a ContentNode
1089 pPos->AssignStartIndex(*pPos->GetNode().GetContentNode());
1090}
1091
1093{
1094 // jump to section's beginning
1096 pPos->nContent.Assign(pPos->GetNode().GetContentNode(), 0);
1097}
1098
1101{
1102 // jump to section's beginning/end
1103 SwNodes& rNodes = pPos->GetNodes();
1104 sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->GetNode() );
1105 if( pPos->GetNode() < *rNodes.GetEndOfContent().StartOfSectionNode() )
1106 nLevel--;
1107 do { SwNodes::GoEndOfSection( &pPos->nNode ); } while( nLevel-- );
1108
1109 // now on an EndNode, thus to the previous ContentNode
1110 if( SwContentNode* pCNd = GoPreviousNds( &pPos->nNode, true ) )
1111 pPos->AssignEndIndex(*pCNd);
1112}
1113
1115{
1117 SwContentNode* pCNd = pPos->nNode.GetNode().GetContentNode();
1118 pPos->nContent.Assign(pCNd, pCNd ? pCNd->Len() : 0);
1119}
1120
1121bool GoInDoc( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1122{
1123 (*fnMove.fnDoc)( rPam.GetPoint() );
1124 return true;
1125}
1126
1127bool GoInSection( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1128{
1129 (*fnMove.fnSections)( rPam.GetPoint() );
1130 return true;
1131}
1132
1133bool GoInNode( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1134{
1135 SwContentNode *pNd = (*fnMove.fnNds)( &rPam.GetPoint()->nNode, true );
1136 if( pNd )
1137 rPam.GetPoint()->nContent.Assign( pNd,
1138 ::GetSttOrEnd( &fnMove == &fnMoveForward, *pNd ) );
1139 return pNd;
1140}
1141
1142bool GoInContent( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1143{
1144 if( (*fnMove.fnNd)( &rPam.GetPoint()->GetNode(),
1146 return true;
1147 return GoInNode( rPam, fnMove );
1148}
1149
1150bool GoInContentCells( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1151{
1152 if( (*fnMove.fnNd)( &rPam.GetPoint()->GetNode(),
1154 return true;
1155 return GoInNode( rPam, fnMove );
1156}
1157
1158bool GoInContentSkipHidden( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1159{
1160 if( (*fnMove.fnNd)( &rPam.GetPoint()->GetNode(),
1162 return true;
1163 return GoInNode( rPam, fnMove );
1164}
1165
1167{
1168 if( (*fnMove.fnNd)( &rPam.GetPoint()->GetNode(),
1170 return true;
1171 return GoInNode( rPam, fnMove );
1172}
1173
1174bool GoPrevPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara )
1175{
1176 if( rPam.Move( fnMoveBackward, GoInNode ) )
1177 {
1178 // always on a ContentNode
1179 SwPosition& rPos = *rPam.GetPoint();
1180 SwContentNode * pNd = rPos.GetNode().GetContentNode();
1181 rPos.nContent.Assign( pNd,
1182 ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ) );
1183 return true;
1184 }
1185 return false;
1186}
1187
1188bool GoCurrPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara )
1189{
1190 SwPosition& rPos = *rPam.GetPoint();
1191 SwContentNode * pNd = rPos.GetNode().GetContentNode();
1192 if( pNd )
1193 {
1194 const sal_Int32 nOld = rPos.GetContentIndex();
1195 const sal_Int32 nNew = &aPosPara == &fnMoveForward ? 0 : pNd->Len();
1196 // if already at beginning/end then to the next/previous
1197 if( nOld != nNew )
1198 {
1199 rPos.nContent.Assign( pNd, nNew );
1200 return true;
1201 }
1202 }
1203 // move node to next/previous ContentNode
1204 if( ( &aPosPara==&fnParaStart && nullptr != ( pNd =
1205 GoPreviousNds( &rPos.nNode, true ))) ||
1206 ( &aPosPara==&fnParaEnd && nullptr != ( pNd =
1207 GoNextNds( &rPos.nNode, true ))) )
1208 {
1209 rPos.nContent.Assign( pNd,
1210 ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ));
1211 return true;
1212 }
1213 return false;
1214}
1215
1216bool GoNextPara( SwPaM & rPam, SwMoveFnCollection const & aPosPara )
1217{
1218 if( rPam.Move( fnMoveForward, GoInNode ) )
1219 {
1220 // always on a ContentNode
1221 SwPosition& rPos = *rPam.GetPoint();
1222 SwContentNode * pNd = rPos.GetNode().GetContentNode();
1223 rPos.nContent.Assign( pNd,
1224 ::GetSttOrEnd( &aPosPara == &fnMoveForward, *pNd ) );
1225 return true;
1226 }
1227 return false;
1228}
1229
1230bool GoCurrSection( SwPaM & rPam, SwMoveFnCollection const & fnMove )
1231{
1232 SwPosition& rPos = *rPam.GetPoint();
1233 SwPosition aSavePos( rPos ); // position for comparison
1234 (fnMove.fnSection)( &rPos );
1235 SwContentNode *pNd;
1236 if( nullptr == ( pNd = rPos.GetNode().GetContentNode()) &&
1237 nullptr == ( pNd = (*fnMove.fnNds)( &rPos.nNode, true )) )
1238 {
1239 rPos = aSavePos; // do not change cursor
1240 return false;
1241 }
1242
1243 rPos.nContent.Assign( pNd,
1244 ::GetSttOrEnd( &fnMove == &fnMoveForward, *pNd ) );
1245 return aSavePos != rPos;
1246}
1247
1248OUString SwPaM::GetText() const
1249{
1250 OUStringBuffer aResult;
1251
1252 SwNodeIndex aNodeIndex = Start()->nNode;
1253
1254 // The first node can be already the end node.
1255 // Use a "forever" loop with an exit condition in the middle
1256 // of its body, in order to correctly handle all cases.
1257 bool bIsStartNode = true;
1258 for (;;)
1259 {
1260 const bool bIsEndNode = aNodeIndex == End()->nNode;
1261 SwTextNode * pTextNode = aNodeIndex.GetNode().GetTextNode();
1262
1263 if (pTextNode != nullptr)
1264 {
1265 if (!bIsStartNode)
1266 {
1267 aResult.append(CH_TXTATR_NEWLINE); // use newline for para break
1268 }
1269 const OUString& aTmpStr = pTextNode->GetText();
1270
1271 if (bIsStartNode || bIsEndNode)
1272 {
1273 // Handle corner cases of start/end node(s)
1274 const sal_Int32 nStart = bIsStartNode
1275 ? Start()->GetContentIndex()
1276 : 0;
1277 const sal_Int32 nEnd = bIsEndNode
1278 ? End()->GetContentIndex()
1279 : aTmpStr.getLength();
1280
1281 aResult.append(aTmpStr.subView(nStart, nEnd-nStart));
1282 }
1283 else
1284 {
1285 aResult.append(aTmpStr);
1286 }
1287 }
1288
1289 if (bIsEndNode)
1290 {
1291 break;
1292 }
1293
1294 ++aNodeIndex;
1295 bIsStartNode = false;
1296 }
1297
1298 return aResult.makeStringAndClear();
1299}
1300
1302{
1303 for (SwNodeIndex index(Start()->GetNode()); index <= End()->GetNode(); ++index)
1304 {
1305 if (SwTextNode *const pTextNode = index.GetNode().GetTextNode())
1306 {
1307 // pretend that the PaM marks changed formatting to reformat...
1308 sal_Int32 const nStart(
1309 index == Start()->nNode ? Start()->GetContentIndex() : 0);
1310 // this should work even for length of 0
1311 SwUpdateAttr const aHint(
1312 nStart,
1313 index == End()->nNode
1314 ? End()->GetContentIndex() - nStart
1315 : pTextNode->Len() - nStart,
1316 0);
1317 pTextNode->TriggerNodeUpdate(sw::LegacyModifyHint(&aHint, &aHint));
1318 }
1319 // other node types not invalidated
1320 }
1321}
1322
1324{
1325 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwPaM"));
1326
1327 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("point"));
1328 GetPoint()->dumpAsXml(pWriter);
1329 (void)xmlTextWriterEndElement(pWriter);
1330
1331 if (HasMark())
1332 {
1333 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mark"));
1334 GetMark()->dumpAsXml(pWriter);
1335 (void)xmlTextWriterEndElement(pWriter);
1336 }
1337
1338 (void)xmlTextWriterEndElement(pWriter);
1339}
1340
1341std::ostream &operator <<(std::ostream& s, const SwPaM& pam)
1342{
1343 if( pam.HasMark())
1344 return s << "SwPaM (point " << *pam.GetPoint() << ", mark " << *pam.GetMark() << ")";
1345 else
1346 return s << "SwPaM (point " << *pam.GetPoint() << ")";
1347}
1348
1349
1350/* 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:1224
virtual sal_Int32 Len() const
Definition: node.cxx:1257
Definition: doc.hxx:192
SwSectionFormats & GetSections()
Definition: doc.hxx:1341
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:330
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:406
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:177
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1793
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:187
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.
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:1638
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:84
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:876
SwSectionNode * GetSectionNode()
Definition: node.hxx:635
SwNodeOffset GetIndex() const
Definition: node.hxx:296
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:721
bool IsContentNode() const
Definition: node.hxx:656
SwDoc & GetDoc()
Definition: node.hxx:217
bool IsStartNode() const
Definition: node.hxx:652
SwNodeOffset StartOfSectionIndex() const
Definition: node.hxx:701
bool IsTextNode() const
Definition: node.hxx:664
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:981
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:137
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:705
SwContentNode * GetContentNode()
Definition: node.hxx:643
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:710
static sal_uInt16 GetSectionLevel(const SwNode &rIndex)
get section level at the given position
Definition: nodes.cxx:1268
static void GoEndOfSection(SwNodeIndex *)
Definition: nodes.cxx:1294
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:2531
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1334
static void GoStartOfSection(SwNodeIndex *)
Definition: nodes.cxx:1276
SwNode & GetEndOfRedlines() const
Section for all Redlines.
Definition: ndarr.hxx:160
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:1952
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:2068
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:594
SwPosition m_Bound1
Definition: pam.hxx:188
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: pam.cxx:1323
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:612
void Exchange()
Definition: pam.cxx:626
SwPosition * m_pMark
points at either m_Bound1 or m_Bound2
Definition: pam.hxx:191
virtual ~SwPaM() override
Definition: pam.cxx:582
void Normalize(bool bPointFirst=true)
Normalizes PaM, i.e.
Definition: pam.cxx:670
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:638
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:681
OUString GetText() const
Definition: pam.cxx:1248
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:727
const SwPosition * GetPoint() const
Definition: pam.hxx:261
const SwPosition * Start() const
Definition: pam.hxx:266
void InvalidatePaM()
Definition: pam.cxx:1301
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:82
Array of Undo-history.
Definition: docary.hxx:192
SwSection * GetSection()
Definition: sectfrm.hxx:97
const SwSection & GetSection() const
Definition: node.hxx:567
bool IsProtectFlag() const
Definition: section.hxx:189
bool IsProtect() const
Definition: section.cxx:326
bool IsEditInReadonlyFlag() const
Definition: section.hxx:190
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:86
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:1763
const OUString & GetText() const
Definition: ndtxt.hxx:222
@ PARENT
EXPAND : (Start < nIndex <= End)
Definition: ndtxt.hxx:380
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, 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: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.
void MakeRegion(SwMoveFnCollection const &fnMove, const SwPaM &rOrigRg, std::optional< SwPaM > &rPam)
make a new region
Definition: pam.cxx:657
std::pair< SwTextNode *, SwTextNode * > GetFirstAndLastNode(SwRootFrame const &rLayout, SwNode const &rPos)
Definition: txtfrm.cxx:354
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
constexpr OUStringLiteral ODF_UNHANDLED
void GoEndOfSection(SwPosition *pPos)
Definition: pam.cxx:1114
bool GoCurrPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1188
SwContentNode * GoNextNds(SwNodeIndex *pIdx, bool bChk)
Definition: pam.cxx:394
bool GoInContentSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1158
bool GoPrevPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1174
void GoStartSection(SwPosition *pPos)
Definition: pam.cxx:1079
bool GoInContentCells(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1150
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1133
std::ostream & operator<<(std::ostream &s, const SwPosition &position)
Definition: pam.cxx:283
void GoStartDoc(SwPosition *pPos)
Definition: pam.cxx:1062
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:982
bool GoInDoc(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1121
void GoStartOfSection(SwPosition *pPos)
Definition: pam.cxx:1092
bool GoInContentCellsSkipHidden(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1166
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:702
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:1070
bool GoNextPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1216
bool GoInSection(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1127
void GoEndSection(SwPosition *pPos)
go to the end of the current base section
Definition: pam.cxx:1100
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
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1142
bool GoCurrSection(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1230
auto(*)(SwPaM &rPam, SwMoveFnCollection const &fnMove) -> bool SwGoInDoc
Definition: pam.hxx:171
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:82
GoSection fnSections
Definition: pamtyp.hxx:78
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