1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pam.cxx,v $
10 * $Revision: 1.23.12.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
36 #include <svx/protitem.hxx>
38 #include <pagefrm.hxx>
44 #include <section.hxx>
45 #include <fmtcntnt.hxx>
47 #include <swtable.hxx>
48 #include <crsskip.hxx>
50 // --> FME 2004-06-29 #114856# Formular view
52 #include <fmteiro.hxx>
53 #include <section.hxx>
54 #include <sectfrm.hxx>
56 #include <ndtxt.hxx> // #111827#
61 // fuer den dummen ?MSC-? Compiler
62 inline xub_StrLen
GetSttOrEnd( BOOL bCondition
, const SwCntntNode
& rNd
)
64 return bCondition
? 0 : rNd
.Len();
67 /*************************************************************************
71 |* Beschreibung PAM.DOC
72 |* Ersterstellung VB 4.3.91
73 |* Letzte Aenderung VB 4.3.91
75 *************************************************************************/
78 SwPosition::SwPosition( const SwNodeIndex
& rNodeIndex
, const SwIndex
& rCntnt
)
79 : nNode( rNodeIndex
), nContent( rCntnt
)
83 SwPosition::SwPosition( const SwNodeIndex
& rNodeIndex
)
84 : nNode( rNodeIndex
), nContent( nNode
.GetNode().GetCntntNode() )
88 SwPosition::SwPosition( const SwNode
& rNode
)
89 : nNode( rNode
), nContent( nNode
.GetNode().GetCntntNode() )
93 SwPosition::SwPosition( SwCntntNode
& rNode
, const xub_StrLen nOffset
)
94 : nNode( rNode
), nContent( &rNode
, nOffset
)
99 SwPosition::SwPosition( const SwPosition
& rPos
)
100 : nNode( rPos
.nNode
), nContent( rPos
.nContent
)
104 SwPosition
&SwPosition::operator=(const SwPosition
&rPos
)
107 nContent
= rPos
.nContent
;
112 BOOL
SwPosition::operator<(const SwPosition
&rPos
) const
114 if( nNode
< rPos
.nNode
)
116 if( nNode
== rPos
.nNode
)
117 return ( nContent
< rPos
.nContent
);
122 BOOL
SwPosition::operator>(const SwPosition
&rPos
) const
124 if(nNode
> rPos
.nNode
)
126 if( nNode
== rPos
.nNode
)
127 return ( nContent
> rPos
.nContent
);
132 BOOL
SwPosition::operator<=(const SwPosition
&rPos
) const
134 if(nNode
< rPos
.nNode
)
136 if( nNode
== rPos
.nNode
)
137 return ( nContent
<= rPos
.nContent
);
142 BOOL
SwPosition::operator>=(const SwPosition
&rPos
) const
144 if(nNode
> rPos
.nNode
)
146 if( nNode
== rPos
.nNode
)
147 return ( nContent
>= rPos
.nContent
);
152 BOOL
SwPosition::operator==(const SwPosition
&rPos
) const
155 ( ( nNode
== rPos
.nNode
) && ( nContent
== rPos
.nContent
) ?
160 BOOL
SwPosition::operator!=(const SwPosition
&rPos
) const
162 if( nNode
!= rPos
.nNode
)
164 return ( nContent
!= rPos
.nContent
);
167 SwDoc
* SwPosition::GetDoc() const
169 return nNode
.GetNode().GetDoc();
172 SwComparePosition
ComparePosition(
173 const SwPosition
& rStt1
, const SwPosition
& rEnd1
,
174 const SwPosition
& rStt2
, const SwPosition
& rEnd2
)
176 SwComparePosition nRet
;
184 nRet
= POS_OVERLAP_BEFORE
;
187 else if( rEnd1
== rStt2
)
188 nRet
= POS_COLLIDE_END
;
192 else if( rEnd2
> rStt1
)
196 if( rEnd2
== rEnd1
&& rStt2
== rStt1
)
202 nRet
= POS_OVERLAP_BEHIND
;
204 else if( rEnd2
== rStt1
)
205 nRet
= POS_COLLIDE_START
;
211 SwComparePosition
ComparePosition(
212 const unsigned long nStt1
, const unsigned long nEnd1
,
213 const unsigned long nStt2
, const unsigned long nEnd2
)
215 SwComparePosition nRet
;
223 nRet
= POS_OVERLAP_BEFORE
;
226 else if( nEnd1
== nStt2
)
227 nRet
= POS_COLLIDE_END
;
231 else if( nEnd2
> nStt1
)
235 if( nEnd2
== nEnd1
&& nStt2
== nStt1
)
241 nRet
= POS_OVERLAP_BEHIND
;
243 else if( nEnd2
== nStt1
)
244 nRet
= POS_COLLIDE_START
;
252 enum CHKSECTION
{ Chk_Both
, Chk_One
, Chk_None
};
255 CHKSECTION
lcl_TstIdx( ULONG nSttIdx
, ULONG nEndIdx
, const SwNode
& rEndNd
)
257 ULONG nStt
= rEndNd
.StartOfSectionIndex(), nEnd
= rEndNd
.GetIndex();
258 CHKSECTION eSec
= nStt
< nSttIdx
&& nEnd
>= nSttIdx
? Chk_One
: Chk_None
;
259 if( nStt
< nEndIdx
&& nEnd
>= nEndIdx
)
260 return( eSec
== Chk_One
? Chk_Both
: Chk_One
);
265 BOOL
lcl_ChkOneRange( CHKSECTION eSec
, BOOL bChkSections
,
266 const SwNode
& rBaseEnd
, ULONG nStt
, ULONG nEnd
)
268 if( eSec
!= Chk_Both
)
274 // suche die umspannende Section
275 const SwNodes
& rNds
= rBaseEnd
.GetNodes();
276 const SwNode
*pTmp
, *pNd
= rNds
[ nStt
];
277 if( !pNd
->IsStartNode() )
278 pNd
= pNd
->StartOfSectionNode();
280 if( pNd
== rNds
[ nEnd
]->StartOfSectionNode() )
281 return TRUE
; // der gleiche StartNode, die selbe Section
283 // steht schon auf einem GrundSection Node ? Fehler !!!
284 if( !pNd
->StartOfSectionIndex() )
287 while( ( pTmp
= pNd
->StartOfSectionNode())->EndOfSectionNode() !=
291 ULONG nSttIdx
= pNd
->GetIndex(), nEndIdx
= pNd
->EndOfSectionIndex();
292 return nSttIdx
<= nStt
&& nStt
<= nEndIdx
&&
293 nSttIdx
<= nEnd
&& nEnd
<= nEndIdx
? TRUE
: FALSE
;
297 BOOL
CheckNodesRange( const SwNodeIndex
& rStt
,
298 const SwNodeIndex
& rEnd
, BOOL bChkSection
)
300 const SwNodes
& rNds
= rStt
.GetNodes();
301 ULONG nStt
= rStt
.GetIndex(), nEnd
= rEnd
.GetIndex();
302 CHKSECTION eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfContent() );
303 if( Chk_None
!= eSec
) return eSec
== Chk_Both
? TRUE
: FALSE
;
305 eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfAutotext() );
306 if( Chk_None
!= eSec
)
307 return lcl_ChkOneRange( eSec
, bChkSection
,
308 rNds
.GetEndOfAutotext(), nStt
, nEnd
);
310 eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfPostIts() );
311 if( Chk_None
!= eSec
)
312 return lcl_ChkOneRange( eSec
, bChkSection
,
313 rNds
.GetEndOfPostIts(), nStt
, nEnd
);
315 eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfInserts() );
316 if( Chk_None
!= eSec
)
317 return lcl_ChkOneRange( eSec
, bChkSection
,
318 rNds
.GetEndOfInserts(), nStt
, nEnd
);
320 eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfRedlines() );
321 if( Chk_None
!= eSec
)
322 return lcl_ChkOneRange( eSec
, bChkSection
,
323 rNds
.GetEndOfRedlines(), nStt
, nEnd
);
325 return FALSE
; // liegt irgendwo dazwischen, FEHLER
329 BOOL
GoNext(SwNode
* pNd
, SwIndex
* pIdx
, USHORT nMode
)
331 if( pNd
->IsCntntNode() )
332 return ((SwCntntNode
*)pNd
)->GoNext( pIdx
, nMode
);
337 BOOL
GoPrevious( SwNode
* pNd
, SwIndex
* pIdx
, USHORT nMode
)
339 if( pNd
->IsCntntNode() )
340 return ((SwCntntNode
*)pNd
)->GoPrevious( pIdx
, nMode
);
345 SwCntntNode
* GoNextNds( SwNodeIndex
* pIdx
, BOOL bChk
)
347 SwNodeIndex
aIdx( *pIdx
);
348 SwCntntNode
* pNd
= aIdx
.GetNodes().GoNext( &aIdx
);
351 if( bChk
&& 1 != aIdx
.GetIndex() - pIdx
->GetIndex() &&
352 !CheckNodesRange( *pIdx
, aIdx
, TRUE
) )
361 SwCntntNode
* GoPreviousNds( SwNodeIndex
* pIdx
, BOOL bChk
)
363 SwNodeIndex
aIdx( *pIdx
);
364 SwCntntNode
* pNd
= aIdx
.GetNodes().GoPrevious( &aIdx
);
367 if( bChk
&& 1 != pIdx
->GetIndex() - aIdx
.GetIndex() &&
368 !CheckNodesRange( *pIdx
, aIdx
, TRUE
) )
376 // ----------------------------------------------------------------------
378 /*************************************************************************
382 |* Beschreibung PAM.DOC
383 |* Ersterstellung VB 4.3.91
384 |* Letzte Aenderung JP 6.5.91
386 *************************************************************************/
388 SwPaM::SwPaM( const SwPosition
& rPos
, SwPaM
* pRing
)
391 , m_Bound2( rPos
.nNode
.GetNode().GetNodes() ) // default initialize
392 , m_pPoint( &m_Bound1
)
393 , m_pMark( m_pPoint
)
394 , m_bIsInFrontOfLabel( false )
398 SwPaM::SwPaM( const SwPosition
& rMark
, const SwPosition
& rPoint
, SwPaM
* pRing
)
402 , m_pPoint( &m_Bound2
)
403 , m_pMark( &m_Bound1
)
404 , m_bIsInFrontOfLabel( false )
408 SwPaM::SwPaM( const SwNodeIndex
& rMark
, const SwNodeIndex
& rPoint
,
409 long nMarkOffset
, long nPointOffset
, SwPaM
* pRing
)
413 , m_pPoint( &m_Bound2
)
414 , m_pMark( &m_Bound1
)
415 , m_bIsInFrontOfLabel( false )
419 m_pMark
->nNode
+= nMarkOffset
;
423 m_pPoint
->nNode
+= nPointOffset
;
426 m_Bound1
.nContent
.Assign( m_Bound1
.nNode
.GetNode().GetCntntNode(), 0 );
427 m_Bound2
.nContent
.Assign( m_Bound2
.nNode
.GetNode().GetCntntNode(), 0 );
430 SwPaM::SwPaM( const SwNode
& rMark
, const SwNode
& rPoint
,
431 long nMarkOffset
, long nPointOffset
, SwPaM
* pRing
)
435 , m_pPoint( &m_Bound2
)
436 , m_pMark( &m_Bound1
)
437 , m_bIsInFrontOfLabel( false )
441 m_pMark
->nNode
+= nMarkOffset
;
445 m_pPoint
->nNode
+= nPointOffset
;
448 m_Bound1
.nContent
.Assign( m_Bound1
.nNode
.GetNode().GetCntntNode(), 0 );
449 m_Bound2
.nContent
.Assign( m_Bound2
.nNode
.GetNode().GetCntntNode(), 0 );
452 SwPaM::SwPaM( const SwNodeIndex
& rMark
, xub_StrLen nMarkCntnt
,
453 const SwNodeIndex
& rPoint
, xub_StrLen nPointCntnt
, SwPaM
* pRing
)
457 , m_pPoint( &m_Bound2
)
458 , m_pMark( &m_Bound1
)
459 , m_bIsInFrontOfLabel( false )
461 m_pPoint
->nContent
.Assign( rPoint
.GetNode().GetCntntNode(), nPointCntnt
);
462 m_pMark
->nContent
.Assign( rMark
.GetNode().GetCntntNode(), nMarkCntnt
);
465 SwPaM::SwPaM( const SwNode
& rMark
, xub_StrLen nMarkCntnt
,
466 const SwNode
& rPoint
, xub_StrLen nPointCntnt
, SwPaM
* pRing
)
470 , m_pPoint( &m_Bound2
)
471 , m_pMark( &m_Bound1
)
472 , m_bIsInFrontOfLabel( false )
474 m_pPoint
->nContent
.Assign( m_pPoint
->nNode
.GetNode().GetCntntNode(),
476 m_pMark
->nContent
.Assign( m_pMark
->nNode
.GetNode().GetCntntNode(),
480 SwPaM::SwPaM( const SwNode
& rNode
, xub_StrLen nCntnt
, SwPaM
* pRing
)
483 , m_Bound2( m_Bound1
.nNode
.GetNode().GetNodes() ) // default initialize
484 , m_pPoint( &m_Bound1
)
485 , m_pMark( &m_Bound1
)
486 , m_bIsInFrontOfLabel( false )
488 m_pPoint
->nContent
.Assign( m_pPoint
->nNode
.GetNode().GetCntntNode(),
492 SwPaM::SwPaM( const SwNodeIndex
& rNodeIdx
, xub_StrLen nCntnt
, SwPaM
* pRing
)
494 , m_Bound1( rNodeIdx
)
495 , m_Bound2( rNodeIdx
.GetNode().GetNodes() ) // default initialize
496 , m_pPoint( &m_Bound1
)
497 , m_pMark( &m_Bound1
)
498 , m_bIsInFrontOfLabel( false )
500 m_pPoint
->nContent
.Assign( rNodeIdx
.GetNode().GetCntntNode(), nCntnt
);
505 // @@@ semantic: no copy ctor.
506 SwPaM::SwPaM( SwPaM
&rPam
)
508 , m_Bound1( *(rPam
.m_pPoint
) )
509 , m_Bound2( *(rPam
.m_pMark
) )
510 , m_pPoint( &m_Bound1
), m_pMark( rPam
.HasMark() ? &m_Bound2
: m_pPoint
)
511 , m_bIsInFrontOfLabel( false )
515 // @@@ semantic: no copy assignment for super class Ring.
516 SwPaM
&SwPaM::operator=( const SwPaM
&rPam
)
518 *m_pPoint
= *( rPam
.m_pPoint
);
519 if ( rPam
.HasMark() )
522 *m_pMark
= *( rPam
.m_pMark
);
531 void SwPaM::SetMark()
533 if (m_pPoint
== &m_Bound1
)
541 (*m_pMark
) = (*m_pPoint
);
546 void SwPaM::Exchange()
548 if (m_pPoint
!= m_pMark
)
550 SwPosition
*pTmp
= m_pPoint
;
557 // Bewegen des Cursors
560 BOOL
SwPaM::Move( SwMoveFn fnMove
, SwGoInDoc fnGo
)
562 BOOL bRet
= (*fnGo
)( *this, fnMove
);
564 m_bIsInFrontOfLabel
= false;
570 /*************************************************************************
572 |* void SwPaM::MakeRegion( SwMoveFn, SwPaM*, const SwPaM* )
574 |* Beschreibung Setzt den 1. SwPaM auf den uebergebenen SwPaM
575 |* oder setzt auf den Anfang oder Ende vom Document.
576 |* SPoint bleibt auf der Position stehen, GetMark aendert
577 |* sich entsprechend !
579 |* Parameter SwDirection gibt an, ob an Anfang / Ende
580 |* SwPaM * der zu setzende Bereich
581 |* const SwPaM& der enventuell vorgegeben Bereich
582 |* Return-Werte SwPaM* der entsprehend neu gesetzte Bereich
584 |* Ersterstellung JP 26.04.91
585 |* Letzte Aenderung JP 26.04.91
587 *************************************************************************/
590 SwPaM
* SwPaM::MakeRegion( SwMoveFn fnMove
, const SwPaM
* pOrigRg
)
595 pPam
= new SwPaM( *m_pPoint
);
596 pPam
->SetMark(); // setze Anfang fest
597 pPam
->Move( fnMove
, fnGoSection
); // an Anfang / Ende vom Node
599 // stelle SPoint wieder auf alte Position, GetMark auf das "Ende"
604 pPam
= new SwPaM( *(SwPaM
*)pOrigRg
); // die Suchregion ist vorgegeben
605 // sorge dafuer, dass SPoint auf dem "echten" StartPunkt steht
606 // FORWARD --> SPoint immer kleiner als GetMark
607 // BACKWARD --> SPoint immer groesser als GetMark
608 if( (pPam
->GetMark()->*fnMove
->fnCmpOp
)( *pPam
->GetPoint() ) )
614 SwPaM
& SwPaM::Normalize(BOOL bPointFirst
)
617 if ( ( bPointFirst
&& *m_pPoint
> *m_pMark
) ||
618 (!bPointFirst
&& *m_pPoint
< *m_pMark
) )
626 USHORT
SwPaM::GetPageNum( BOOL bAtPoint
, const Point
* pLayPos
)
628 // return die Seitennummer am Cursor
629 // (fuer Reader + Seitengebundene Rahmen)
630 const SwCntntFrm
* pCFrm
;
631 const SwPageFrm
*pPg
;
632 const SwCntntNode
*pNd
;
633 const SwPosition
* pPos
= bAtPoint
? m_pPoint
: m_pMark
;
635 if( 0 != ( pNd
= pPos
->nNode
.GetNode().GetCntntNode() ) &&
636 0 != ( pCFrm
= pNd
->GetFrm( pLayPos
, pPos
, FALSE
)) &&
637 0 != ( pPg
= pCFrm
->FindPageFrm() ))
638 return pPg
->GetPhyPageNum();
642 // --> FME 2004-06-29 #114856# Formular view
643 // See also SwCrsrShell::IsCrsrReadonly()
644 const SwFrm
* lcl_FindEditInReadonlyFrm( const SwFrm
& rFrm
)
646 const SwFrm
* pRet
= 0;
648 const SwFlyFrm
* pFly
;
649 const SwSectionFrm
* pSectionFrm
;
651 if( rFrm
.IsInFly() &&
652 (pFly
= rFrm
.FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
654 !pFly
->Lower()->IsNoTxtFrm() )
658 else if ( rFrm
.IsInSct() &&
659 0 != ( pSectionFrm
= rFrm
.FindSctFrm() )->GetSection() &&
660 pSectionFrm
->GetSection()->IsEditInReadonlyFlag() )
669 // steht in etwas geschuetztem oder in die Selektion umspannt
670 // etwas geschuetztes.
671 BOOL
SwPaM::HasReadonlySel( bool bFormView
) const
675 const SwCntntNode
*pNd
;
676 const SwCntntFrm
*pFrm
;
678 if( 0 != ( pNd
= GetPoint()->nNode
.GetNode().GetCntntNode() ))
679 pFrm
= pNd
->GetFrm( &aTmpPt
, GetPoint(), FALSE
);
683 // --> FME 2004-06-29 #114856# Formular view
684 // Will be set if point/mark are inside edit-in-readonly environment
685 const SwFrm
* pSttEIRFrm
= 0;
686 const SwFrm
* pEndEIRFrm
= 0;
688 if( pFrm
&& ( pFrm
->IsProtected() ||
689 // --> FME 2004-06-29 #114856# Formular view
691 0 == ( pSttEIRFrm
= lcl_FindEditInReadonlyFrm( *pFrm
) ) ) ) )
696 const SwSectionNode
* pSNd
= pNd
->GetSectionNode();
697 if( pSNd
&& ( pSNd
->GetSection().IsProtectFlag() ||
698 // --> FME 2004-06-29 #114856# Formular view
699 (bFormView
&& !pSNd
->GetSection().IsEditInReadonlyFlag()) ) )
704 if( !bRet
&& HasMark() && GetPoint()->nNode
!= GetMark()->nNode
)
706 if( 0 != ( pNd
= GetMark()->nNode
.GetNode().GetCntntNode() ))
707 pFrm
= pNd
->GetFrm( &aTmpPt
, GetMark(), FALSE
);
711 if( pFrm
&& ( pFrm
->IsProtected() ||
712 // --> FME 2004-06-29 #114856# Formular view
714 0 == ( pEndEIRFrm
= lcl_FindEditInReadonlyFrm( *pFrm
) ) ) ) )
719 const SwSectionNode
* pSNd
= pNd
->GetSectionNode();
720 if( pSNd
&& ( pSNd
->GetSection().IsProtectFlag() ||
721 // --> FME 2004-06-29 #114856# Formular view
722 (bFormView
&& !pSNd
->GetSection().IsEditInReadonlyFlag()) ) )
727 // --> FME 2004-06-29 #114856# Formular view
728 if ( !bRet
&& bFormView
)
730 // Check if start and end frame are inside the _same_
731 // edit-in-readonly-environment. Otherwise we better return 'true'
732 if ( pSttEIRFrm
!= pEndEIRFrm
)
737 // oder sollte eine geschuetzte Section innerhalb der
741 ULONG nSttIdx
= GetMark()->nNode
.GetIndex(),
742 nEndIdx
= GetPoint()->nNode
.GetIndex();
743 if( nEndIdx
<= nSttIdx
)
745 ULONG nTmp
= nSttIdx
;
750 // wenn ein geschuetzter Bereich zwischen den Nodes stehen soll,
751 // muss die Selektion selbst schon x Nodes umfassen.
752 // (TxtNd, SectNd, TxtNd, EndNd, TxtNd )
753 if( nSttIdx
+ 3 < nEndIdx
)
755 const SwSectionFmts
& rFmts
= GetDoc()->GetSections();
756 for( USHORT n
= rFmts
.Count(); n
; )
758 const SwSectionFmt
* pFmt
= rFmts
[ --n
];
759 if( pFmt
->GetProtect().IsCntntProtected() )
761 const SwFmtCntnt
& rCntnt
= pFmt
->GetCntnt(FALSE
);
762 ASSERT( rCntnt
.GetCntntIdx(), "wo ist der SectionNode?" );
763 ULONG nIdx
= rCntnt
.GetCntntIdx()->GetIndex();
764 if( nSttIdx
<= nIdx
&& nEndIdx
>= nIdx
&&
765 rCntnt
.GetCntntIdx()->GetNode().GetNodes().IsDocNodes() )
767 /* // ist es keine gelinkte Section, dann kann sie auch
768 // nicht mitselektiert werden
769 const SwSection& rSect = *pFmt->GetSection();
770 if( CONTENT_SECTION == rSect.GetType() )
782 #ifdef CHECK_CELL_READONLY
783 //JP 22.01.99: bisher wurden Tabelle, die in der Text-Selektion standen
784 // nicht beachtet. Wollte man das haben, dann muss dieser
785 // Code freigeschaltet werden
789 // dann noch ueber alle Tabellen
790 const SwFrmFmts
& rFmts
= *GetDoc()->GetTblFrmFmts();
791 for( n
= rFmts
.Count(); n
; )
793 SwFrmFmt
* pFmt
= (SwFrmFmt
*)rFmts
[ --n
];
794 const SwTable
* pTbl
= SwTable::FindTable( pFmt
);
795 ULONG nIdx
= pTbl
? pTbl
->GetTabSortBoxes()[0]->GetSttIdx()
797 if( nSttIdx
<= nIdx
&& nEndIdx
>= nIdx
)
799 // dann teste mal alle Boxen
800 const SwTableSortBoxes
& rBoxes
= pTbl
->GetTabSortBoxes();
802 for( USHORT i
= rBoxes
.Count(); i
; )
803 if( rBoxes
[ --i
]->GetFrmFmt()->GetProtect().
820 // TODO: Form Protection when Enhanced Fields are enabled
822 const SwDoc
*pDoc
= GetDoc();
823 sw::mark::IMark
* pA
= NULL
;
824 sw::mark::IMark
* pB
= NULL
;
827 const IDocumentMarkAccess
* pMarksAccess
= pDoc
->getIDocumentMarkAccess( );
828 pA
= GetPoint() ? pMarksAccess
->getFieldmarkFor( *GetPoint( ) ) : NULL
;
829 pB
= GetMark( ) ? pMarksAccess
->getFieldmarkFor( *GetMark( ) ) : pA
;
832 bool bProtectForm
= pDoc
->get( IDocumentSettingAccess::PROTECT_FORM
);
834 bRet
|= ( pA
== NULL
|| pB
== NULL
);
839 //-------------------- Suche nach Formaten( FormatNamen ) -----------------
841 // die Funktion gibt in Suchrichtung den folgenden Node zurueck.
842 // Ist in der Richtung keiner mehr vorhanden oder ist dieser ausserhalb
843 // des Bereiches, wird ein 0 Pointer returnt.
844 // Das rbFirst gibt an, ob es man zu erstenmal einen Node holt. Ist das der
845 // Fall, darf die Position vom Pam nicht veraendert werden!
848 SwCntntNode
* GetNode( SwPaM
& rPam
, BOOL
& rbFirst
, SwMoveFn fnMove
,
851 SwCntntNode
* pNd
= 0;
853 if( ((*rPam
.GetPoint()).*fnMove
->fnCmpOp
)( *rPam
.GetMark() ) ||
854 ( *rPam
.GetPoint() == *rPam
.GetMark() && rbFirst
) )
859 pNd
= rPam
.GetCntntNode();
864 0 == ( pFrm
= pNd
->GetFrm()) ||
865 ( !bInReadOnly
&& pFrm
->IsProtected() ) ||
866 (pFrm
->IsTxtFrm() && ((SwTxtFrm
*)pFrm
)->IsHiddenNow())
868 ( !bInReadOnly
&& pNd
->FindSectionNode() &&
869 pNd
->FindSectionNode()->GetSection().IsProtect()
878 if( !pNd
) // steht Cursor auf keinem ContentNode ?
880 SwPosition
aPos( *rPam
.GetPoint() );
881 BOOL bSrchForward
= fnMove
== fnMoveForward
;
882 SwNodes
& rNodes
= aPos
.nNode
.GetNodes();
884 // zum naechsten / vorherigen ContentNode
885 // Funktioniert noch alles, wenn die Uerbpruefung vom ueberspringen der
886 // Sektions herausgenommen wird ??
887 // if( (*fnMove->fnNds)( rNodes, &aPos.nNode ) )
891 ? rNodes
.GoNextSection( &aPos
.nNode
, TRUE
, !bInReadOnly
)
892 : rNodes
.GoPrevSection( &aPos
.nNode
, TRUE
, !bInReadOnly
);
895 aPos
.nContent
.Assign( pNd
, ::GetSttOrEnd( bSrchForward
,*pNd
));
896 // liegt Position immer noch im Bereich ?
897 if( (aPos
.*fnMove
->fnCmpOp
)( *rPam
.GetMark() ) )
899 // nur in der AutoTextSection koennen Node stehen, die
900 // nicht angezeigt werden !!
901 if( 0 == ( pFrm
= pNd
->GetFrm()) ||
902 ( !bInReadOnly
&& pFrm
->IsProtected() ) ||
903 ( pFrm
->IsTxtFrm() &&
904 ((SwTxtFrm
*)pFrm
)->IsHiddenNow() ) )
906 // rNodes[ rNodes.EndOfAutotext ]->StartOfSection().GetIndex()
907 // < aPos.nNode.GetIndex() && aPos.nNode.GetIndex()
908 // < rNodes.EndOfAutotext.GetIndex() &&
909 // 0 == ( pFrm = pNd->GetFrm()) &&
910 // pFrm->IsProtected() )
913 continue; // suche weiter
915 *(SwPosition
*)rPam
.GetPoint() = aPos
;
918 pNd
= 0; // kein gueltiger Node
928 // ----------------------------------------------------------------------
930 // hier folgen die Move-Methoden ( Foward, Backward; Content, Node, Doc )
933 void GoStartDoc( SwPosition
* pPos
)
935 SwNodes
& rNodes
= pPos
->nNode
.GetNodes();
936 pPos
->nNode
= *rNodes
.GetEndOfContent().StartOfSectionNode();
937 // es muss immer ein ContentNode gefunden werden !!
938 SwCntntNode
* pCNd
= rNodes
.GoNext( &pPos
->nNode
);
940 pCNd
->MakeStartIndex( &pPos
->nContent
);
944 void GoEndDoc( SwPosition
* pPos
)
946 SwNodes
& rNodes
= pPos
->nNode
.GetNodes();
947 pPos
->nNode
= rNodes
.GetEndOfContent();
948 SwCntntNode
* pCNd
= GoPreviousNds( &pPos
->nNode
, TRUE
);
950 pCNd
->MakeEndIndex( &pPos
->nContent
);
954 void GoStartSection( SwPosition
* pPos
)
956 // springe zum Anfang der Section
957 SwNodes
& rNodes
= pPos
->nNode
.GetNodes();
958 USHORT nLevel
= rNodes
.GetSectionLevel( pPos
->nNode
);
959 if( pPos
->nNode
< rNodes
.GetEndOfContent().StartOfSectionIndex() )
961 do { rNodes
.GoStartOfSection( &pPos
->nNode
); } while( nLevel
-- );
963 // steht jetzt schon auf einem CntntNode
964 pPos
->nNode
.GetNode().GetCntntNode()->MakeStartIndex( &pPos
->nContent
);
967 // gehe an das Ende der akt. Grund-Section
970 void GoEndSection( SwPosition
* pPos
)
972 // springe zum Anfang/Ende der Section
973 SwNodes
& rNodes
= pPos
->nNode
.GetNodes();
974 USHORT nLevel
= rNodes
.GetSectionLevel( pPos
->nNode
);
975 if( pPos
->nNode
< rNodes
.GetEndOfContent().StartOfSectionIndex() )
977 do { rNodes
.GoEndOfSection( &pPos
->nNode
); } while( nLevel
-- );
979 // steht jetzt auf einem EndNode, also zum vorherigen CntntNode
980 if( GoPreviousNds( &pPos
->nNode
, TRUE
) )
981 pPos
->nNode
.GetNode().GetCntntNode()->MakeEndIndex( &pPos
->nContent
);
986 BOOL
GoInDoc( SwPaM
& rPam
, SwMoveFn fnMove
)
988 (*fnMove
->fnDoc
)( rPam
.GetPoint() );
993 BOOL
GoInSection( SwPaM
& rPam
, SwMoveFn fnMove
)
995 (*fnMove
->fnSections
)( (SwPosition
*)rPam
.GetPoint() );
1000 BOOL
GoInNode( SwPaM
& rPam
, SwMoveFn fnMove
)
1002 SwCntntNode
*pNd
= (*fnMove
->fnNds
)( &rPam
.GetPoint()->nNode
, TRUE
);
1004 rPam
.GetPoint()->nContent
.Assign( pNd
,
1005 ::GetSttOrEnd( fnMove
== fnMoveForward
, *pNd
) );
1010 BOOL
GoInCntnt( SwPaM
& rPam
, SwMoveFn fnMove
)
1012 if( (*fnMove
->fnNd
)( &rPam
.GetPoint()->nNode
.GetNode(),
1013 &rPam
.GetPoint()->nContent
, CRSR_SKIP_CHARS
))
1015 return GoInNode( rPam
, fnMove
);
1018 BOOL
GoInCntntCells( SwPaM
& rPam
, SwMoveFn fnMove
)
1020 if( (*fnMove
->fnNd
)( &rPam
.GetPoint()->nNode
.GetNode(),
1021 &rPam
.GetPoint()->nContent
, CRSR_SKIP_CELLS
))
1023 return GoInNode( rPam
, fnMove
);
1026 BOOL
GoInCntntSkipHidden( SwPaM
& rPam
, SwMoveFn fnMove
)
1028 if( (*fnMove
->fnNd
)( &rPam
.GetPoint()->nNode
.GetNode(),
1029 &rPam
.GetPoint()->nContent
, CRSR_SKIP_CHARS
| CRSR_SKIP_HIDDEN
) )
1031 return GoInNode( rPam
, fnMove
);
1034 BOOL
GoInCntntCellsSkipHidden( SwPaM
& rPam
, SwMoveFn fnMove
)
1036 if( (*fnMove
->fnNd
)( &rPam
.GetPoint()->nNode
.GetNode(),
1037 &rPam
.GetPoint()->nContent
, CRSR_SKIP_CELLS
| CRSR_SKIP_HIDDEN
) )
1039 return GoInNode( rPam
, fnMove
);
1044 // --------- Funktionsdefinitionen fuer die SwCrsrShell --------------
1047 BOOL
GoPrevPara( SwPaM
& rPam
, SwPosPara aPosPara
)
1049 if( rPam
.Move( fnMoveBackward
, fnGoNode
) )
1051 // steht immer auf einem ContentNode !
1052 SwPosition
& rPos
= *rPam
.GetPoint();
1053 SwCntntNode
* pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1054 rPos
.nContent
.Assign( pNd
,
1055 ::GetSttOrEnd( aPosPara
== fnMoveForward
, *pNd
) );
1062 BOOL
GoCurrPara( SwPaM
& rPam
, SwPosPara aPosPara
)
1064 SwPosition
& rPos
= *rPam
.GetPoint();
1065 SwCntntNode
* pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1068 xub_StrLen nOld
= rPos
.nContent
.GetIndex(),
1069 nNew
= aPosPara
== fnMoveForward
? 0 : pNd
->Len();
1070 // stand er schon auf dem Anfang/Ende dann zum naechsten/vorherigen
1073 rPos
.nContent
.Assign( pNd
, nNew
);
1077 // den Node noch etwas bewegen ( auf den naechsten/vorh. CntntNode)
1078 if( ( aPosPara
==fnParaStart
&& 0 != ( pNd
=
1079 GoPreviousNds( &rPos
.nNode
, TRUE
))) ||
1080 ( aPosPara
==fnParaEnd
&& 0 != ( pNd
=
1081 GoNextNds( &rPos
.nNode
, TRUE
))) )
1083 rPos
.nContent
.Assign( pNd
,
1084 ::GetSttOrEnd( aPosPara
== fnMoveForward
, *pNd
));
1091 BOOL
GoNextPara( SwPaM
& rPam
, SwPosPara aPosPara
)
1093 if( rPam
.Move( fnMoveForward
, fnGoNode
) )
1095 // steht immer auf einem ContentNode !
1096 SwPosition
& rPos
= *rPam
.GetPoint();
1097 SwCntntNode
* pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1098 rPos
.nContent
.Assign( pNd
,
1099 ::GetSttOrEnd( aPosPara
== fnMoveForward
, *pNd
) );
1107 BOOL
GoCurrSection( SwPaM
& rPam
, SwMoveFn fnMove
)
1109 SwPosition
& rPos
= *rPam
.GetPoint();
1110 SwPosition
aSavePos( rPos
); // eine Vergleichsposition
1111 SwNodes
& rNds
= aSavePos
.nNode
.GetNodes();
1112 (rNds
.*fnMove
->fnSection
)( &rPos
.nNode
);
1114 if( 0 == ( pNd
= rPos
.nNode
.GetNode().GetCntntNode()) &&
1115 0 == ( pNd
= (*fnMove
->fnNds
)( &rPos
.nNode
, TRUE
)) )
1117 rPos
= aSavePos
; // Cusror nicht veraendern
1121 rPos
.nContent
.Assign( pNd
,
1122 ::GetSttOrEnd( fnMove
== fnMoveForward
, *pNd
) );
1123 return aSavePos
!= rPos
;
1127 BOOL
GoNextSection( SwPaM
& rPam
, SwMoveFn fnMove
)
1129 SwPosition
& rPos
= *rPam
.GetPoint();
1130 SwPosition
aSavePos( rPos
); // eine Vergleichsposition
1131 SwNodes
& rNds
= aSavePos
.nNode
.GetNodes();
1132 rNds
.GoEndOfSection( &rPos
.nNode
);
1134 // kein weiterer ContentNode vorhanden ?
1135 if( !GoInCntnt( rPam
, fnMoveForward
) )
1137 rPos
= aSavePos
; // Cusror nicht veraendern
1140 (rNds
.*fnMove
->fnSection
)( &rPos
.nNode
);
1141 SwCntntNode
*pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1142 rPos
.nContent
.Assign( pNd
,
1143 ::GetSttOrEnd( fnMove
== fnMoveForward
, *pNd
) );
1148 BOOL
GoPrevSection( SwPaM
& rPam
, SwMoveFn fnMove
)
1150 SwPosition
& rPos
= *rPam
.GetPoint();
1151 SwPosition
aSavePos( rPos
); // eine Vergleichsposition
1152 SwNodes
& rNds
= aSavePos
.nNode
.GetNodes();
1153 rNds
.GoStartOfSection( &rPos
.nNode
);
1155 // kein weiterer ContentNode vorhanden ?
1156 if( !GoInCntnt( rPam
, fnMoveBackward
))
1158 rPos
= aSavePos
; // Cusror nicht veraendern
1161 (rNds
.*fnMove
->fnSection
)( &rPos
.nNode
);
1162 SwCntntNode
*pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1163 rPos
.nContent
.Assign( pNd
,
1164 ::GetSttOrEnd( fnMove
== fnMoveForward
, *pNd
));
1169 String
SwPaM::GetTxt() const
1173 SwNodeIndex aNodeIndex
= Start()->nNode
;
1175 /* The first node can be the end node. A first end node must be
1176 handled, too. There fore do ... while and no incrementing of
1177 aNodeIndex in the first pass.
1189 SwTxtNode
* pTxtNode
= aNodeIndex
.GetNode().GetTxtNode();
1191 if (pTxtNode
!= NULL
)
1193 const String
& aTmpStr
= pTxtNode
->GetTxt();
1195 if (aNodeIndex
== Start()->nNode
)
1198 if (End()->nNode
== aNodeIndex
)
1199 nEnd
= End()->nContent
.GetIndex();
1201 nEnd
= aTmpStr
.Len();
1203 aResult
+= aTmpStr
.Copy(Start()->nContent
.GetIndex(),
1204 nEnd
- Start()->nContent
.GetIndex()) ;
1206 else if (aNodeIndex
== End()->nNode
)
1207 aResult
+= aTmpStr
.Copy(0, End()->nContent
.GetIndex());
1212 while (aNodeIndex
!= End()->nNode
);
1217 BOOL
SwPaM::Overlap(const SwPaM
& a
, const SwPaM
& b
)
1219 return !(*b
.End() <= *a
.Start() || *a
.End() <= *b
.End());
1222 void SwPaM::Invalidate()
1224 const SwNode
*_pNd
=this->GetNode();
1225 const SwTxtNode
*_pTxtNd
=(_pNd
!=NULL
?_pNd
->GetTxtNode():NULL
);
1226 if (_pTxtNd
!=NULL
) {
1227 //pretent we've added a char to force layout to recalc the portion...
1228 SwInsChr
aHint(_pTxtNd
->GetIndex());
1229 SwModify
*_pModify
=(SwModify
*)_pTxtNd
;
1230 _pModify
->Modify( 0, &aHint
);
1234 BOOL
SwPaM::LessThan(const SwPaM
& a
, const SwPaM
& b
)
1236 return (*a
.Start() < *b
.Start()) || (*a
.Start() == *b
.Start() && *a
.End() < *b
.End());