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
)
206 nRet
= POS_OVERLAP_BEHIND
;
209 else if( rEnd2
== rStt1
)
210 nRet
= POS_COLLIDE_START
;
216 SwComparePosition
ComparePosition(
217 const unsigned long nStt1
, const unsigned long nEnd1
,
218 const unsigned long nStt2
, const unsigned long nEnd2
)
220 SwComparePosition nRet
;
228 nRet
= POS_OVERLAP_BEFORE
;
231 else if( nEnd1
== nStt2
)
232 nRet
= POS_COLLIDE_END
;
236 else if( nEnd2
> nStt1
)
240 if( nEnd2
== nEnd1
&& nStt2
== nStt1
)
250 nRet
= POS_OVERLAP_BEHIND
;
253 else if( nEnd2
== nStt1
)
254 nRet
= POS_COLLIDE_START
;
262 enum CHKSECTION
{ Chk_Both
, Chk_One
, Chk_None
};
265 CHKSECTION
lcl_TstIdx( ULONG nSttIdx
, ULONG nEndIdx
, const SwNode
& rEndNd
)
267 ULONG nStt
= rEndNd
.StartOfSectionIndex(), nEnd
= rEndNd
.GetIndex();
268 CHKSECTION eSec
= nStt
< nSttIdx
&& nEnd
>= nSttIdx
? Chk_One
: Chk_None
;
269 if( nStt
< nEndIdx
&& nEnd
>= nEndIdx
)
270 return( eSec
== Chk_One
? Chk_Both
: Chk_One
);
275 BOOL
lcl_ChkOneRange( CHKSECTION eSec
, BOOL bChkSections
,
276 const SwNode
& rBaseEnd
, ULONG nStt
, ULONG nEnd
)
278 if( eSec
!= Chk_Both
)
284 // suche die umspannende Section
285 const SwNodes
& rNds
= rBaseEnd
.GetNodes();
286 const SwNode
*pTmp
, *pNd
= rNds
[ nStt
];
287 if( !pNd
->IsStartNode() )
288 pNd
= pNd
->StartOfSectionNode();
290 if( pNd
== rNds
[ nEnd
]->StartOfSectionNode() )
291 return TRUE
; // der gleiche StartNode, die selbe Section
293 // steht schon auf einem GrundSection Node ? Fehler !!!
294 if( !pNd
->StartOfSectionIndex() )
297 while( ( pTmp
= pNd
->StartOfSectionNode())->EndOfSectionNode() !=
301 ULONG nSttIdx
= pNd
->GetIndex(), nEndIdx
= pNd
->EndOfSectionIndex();
302 return nSttIdx
<= nStt
&& nStt
<= nEndIdx
&&
303 nSttIdx
<= nEnd
&& nEnd
<= nEndIdx
? TRUE
: FALSE
;
307 BOOL
CheckNodesRange( const SwNodeIndex
& rStt
,
308 const SwNodeIndex
& rEnd
, BOOL bChkSection
)
310 const SwNodes
& rNds
= rStt
.GetNodes();
311 ULONG nStt
= rStt
.GetIndex(), nEnd
= rEnd
.GetIndex();
312 CHKSECTION eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfContent() );
313 if( Chk_None
!= eSec
) return eSec
== Chk_Both
? TRUE
: FALSE
;
315 eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfAutotext() );
316 if( Chk_None
!= eSec
)
317 return lcl_ChkOneRange( eSec
, bChkSection
,
318 rNds
.GetEndOfAutotext(), nStt
, nEnd
);
320 eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfPostIts() );
321 if( Chk_None
!= eSec
)
322 return lcl_ChkOneRange( eSec
, bChkSection
,
323 rNds
.GetEndOfPostIts(), nStt
, nEnd
);
325 eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfInserts() );
326 if( Chk_None
!= eSec
)
327 return lcl_ChkOneRange( eSec
, bChkSection
,
328 rNds
.GetEndOfInserts(), nStt
, nEnd
);
330 eSec
= lcl_TstIdx( nStt
, nEnd
, rNds
.GetEndOfRedlines() );
331 if( Chk_None
!= eSec
)
332 return lcl_ChkOneRange( eSec
, bChkSection
,
333 rNds
.GetEndOfRedlines(), nStt
, nEnd
);
335 return FALSE
; // liegt irgendwo dazwischen, FEHLER
339 BOOL
GoNext(SwNode
* pNd
, SwIndex
* pIdx
, USHORT nMode
)
341 if( pNd
->IsCntntNode() )
342 return ((SwCntntNode
*)pNd
)->GoNext( pIdx
, nMode
);
347 BOOL
GoPrevious( SwNode
* pNd
, SwIndex
* pIdx
, USHORT nMode
)
349 if( pNd
->IsCntntNode() )
350 return ((SwCntntNode
*)pNd
)->GoPrevious( pIdx
, nMode
);
355 SwCntntNode
* GoNextNds( SwNodeIndex
* pIdx
, BOOL bChk
)
357 SwNodeIndex
aIdx( *pIdx
);
358 SwCntntNode
* pNd
= aIdx
.GetNodes().GoNext( &aIdx
);
361 if( bChk
&& 1 != aIdx
.GetIndex() - pIdx
->GetIndex() &&
362 !CheckNodesRange( *pIdx
, aIdx
, TRUE
) )
371 SwCntntNode
* GoPreviousNds( SwNodeIndex
* pIdx
, BOOL bChk
)
373 SwNodeIndex
aIdx( *pIdx
);
374 SwCntntNode
* pNd
= aIdx
.GetNodes().GoPrevious( &aIdx
);
377 if( bChk
&& 1 != pIdx
->GetIndex() - aIdx
.GetIndex() &&
378 !CheckNodesRange( *pIdx
, aIdx
, TRUE
) )
386 // ----------------------------------------------------------------------
388 /*************************************************************************
392 |* Beschreibung PAM.DOC
393 |* Ersterstellung VB 4.3.91
394 |* Letzte Aenderung JP 6.5.91
396 *************************************************************************/
398 SwPaM::SwPaM( const SwPosition
& rPos
, SwPaM
* pRing
)
401 , m_Bound2( rPos
.nNode
.GetNode().GetNodes() ) // default initialize
402 , m_pPoint( &m_Bound1
)
403 , m_pMark( m_pPoint
)
404 , m_bIsInFrontOfLabel( false )
408 SwPaM::SwPaM( const SwPosition
& rMark
, const SwPosition
& rPoint
, SwPaM
* pRing
)
412 , m_pPoint( &m_Bound2
)
413 , m_pMark( &m_Bound1
)
414 , m_bIsInFrontOfLabel( false )
418 SwPaM::SwPaM( const SwNodeIndex
& rMark
, const SwNodeIndex
& rPoint
,
419 long nMarkOffset
, long nPointOffset
, SwPaM
* pRing
)
423 , m_pPoint( &m_Bound2
)
424 , m_pMark( &m_Bound1
)
425 , m_bIsInFrontOfLabel( false )
429 m_pMark
->nNode
+= nMarkOffset
;
433 m_pPoint
->nNode
+= nPointOffset
;
436 m_Bound1
.nContent
.Assign( m_Bound1
.nNode
.GetNode().GetCntntNode(), 0 );
437 m_Bound2
.nContent
.Assign( m_Bound2
.nNode
.GetNode().GetCntntNode(), 0 );
440 SwPaM::SwPaM( const SwNode
& rMark
, const SwNode
& rPoint
,
441 long nMarkOffset
, long nPointOffset
, SwPaM
* pRing
)
445 , m_pPoint( &m_Bound2
)
446 , m_pMark( &m_Bound1
)
447 , m_bIsInFrontOfLabel( false )
451 m_pMark
->nNode
+= nMarkOffset
;
455 m_pPoint
->nNode
+= nPointOffset
;
458 m_Bound1
.nContent
.Assign( m_Bound1
.nNode
.GetNode().GetCntntNode(), 0 );
459 m_Bound2
.nContent
.Assign( m_Bound2
.nNode
.GetNode().GetCntntNode(), 0 );
462 SwPaM::SwPaM( const SwNodeIndex
& rMark
, xub_StrLen nMarkCntnt
,
463 const SwNodeIndex
& rPoint
, xub_StrLen nPointCntnt
, SwPaM
* pRing
)
467 , m_pPoint( &m_Bound2
)
468 , m_pMark( &m_Bound1
)
469 , m_bIsInFrontOfLabel( false )
471 m_pPoint
->nContent
.Assign( rPoint
.GetNode().GetCntntNode(), nPointCntnt
);
472 m_pMark
->nContent
.Assign( rMark
.GetNode().GetCntntNode(), nMarkCntnt
);
475 SwPaM::SwPaM( const SwNode
& rMark
, xub_StrLen nMarkCntnt
,
476 const SwNode
& rPoint
, xub_StrLen nPointCntnt
, SwPaM
* pRing
)
480 , m_pPoint( &m_Bound2
)
481 , m_pMark( &m_Bound1
)
482 , m_bIsInFrontOfLabel( false )
484 m_pPoint
->nContent
.Assign( m_pPoint
->nNode
.GetNode().GetCntntNode(),
486 m_pMark
->nContent
.Assign( m_pMark
->nNode
.GetNode().GetCntntNode(),
490 SwPaM::SwPaM( const SwNode
& rNode
, xub_StrLen nCntnt
, SwPaM
* pRing
)
493 , m_Bound2( m_Bound1
.nNode
.GetNode().GetNodes() ) // default initialize
494 , m_pPoint( &m_Bound1
)
495 , m_pMark( &m_Bound1
)
496 , m_bIsInFrontOfLabel( false )
498 m_pPoint
->nContent
.Assign( m_pPoint
->nNode
.GetNode().GetCntntNode(),
502 SwPaM::SwPaM( const SwNodeIndex
& rNodeIdx
, xub_StrLen nCntnt
, SwPaM
* pRing
)
504 , m_Bound1( rNodeIdx
)
505 , m_Bound2( rNodeIdx
.GetNode().GetNodes() ) // default initialize
506 , m_pPoint( &m_Bound1
)
507 , m_pMark( &m_Bound1
)
508 , m_bIsInFrontOfLabel( false )
510 m_pPoint
->nContent
.Assign( rNodeIdx
.GetNode().GetCntntNode(), nCntnt
);
515 // @@@ semantic: no copy ctor.
516 SwPaM::SwPaM( SwPaM
&rPam
)
518 , m_Bound1( *(rPam
.m_pPoint
) )
519 , m_Bound2( *(rPam
.m_pMark
) )
520 , m_pPoint( &m_Bound1
), m_pMark( rPam
.HasMark() ? &m_Bound2
: m_pPoint
)
521 , m_bIsInFrontOfLabel( false )
525 // @@@ semantic: no copy assignment for super class Ring.
526 SwPaM
&SwPaM::operator=( const SwPaM
&rPam
)
528 *m_pPoint
= *( rPam
.m_pPoint
);
529 if ( rPam
.HasMark() )
532 *m_pMark
= *( rPam
.m_pMark
);
541 void SwPaM::SetMark()
543 if (m_pPoint
== &m_Bound1
)
551 (*m_pMark
) = (*m_pPoint
);
556 void SwPaM::Exchange()
558 if (m_pPoint
!= m_pMark
)
560 SwPosition
*pTmp
= m_pPoint
;
567 // Bewegen des Cursors
570 BOOL
SwPaM::Move( SwMoveFn fnMove
, SwGoInDoc fnGo
)
572 BOOL bRet
= (*fnGo
)( *this, fnMove
);
574 m_bIsInFrontOfLabel
= false;
580 /*************************************************************************
582 |* void SwPaM::MakeRegion( SwMoveFn, SwPaM*, const SwPaM* )
584 |* Beschreibung Setzt den 1. SwPaM auf den uebergebenen SwPaM
585 |* oder setzt auf den Anfang oder Ende vom Document.
586 |* SPoint bleibt auf der Position stehen, GetMark aendert
587 |* sich entsprechend !
589 |* Parameter SwDirection gibt an, ob an Anfang / Ende
590 |* SwPaM * der zu setzende Bereich
591 |* const SwPaM& der enventuell vorgegeben Bereich
592 |* Return-Werte SwPaM* der entsprehend neu gesetzte Bereich
594 |* Ersterstellung JP 26.04.91
595 |* Letzte Aenderung JP 26.04.91
597 *************************************************************************/
600 SwPaM
* SwPaM::MakeRegion( SwMoveFn fnMove
, const SwPaM
* pOrigRg
)
605 pPam
= new SwPaM( *m_pPoint
);
606 pPam
->SetMark(); // setze Anfang fest
607 pPam
->Move( fnMove
, fnGoSection
); // an Anfang / Ende vom Node
609 // stelle SPoint wieder auf alte Position, GetMark auf das "Ende"
614 pPam
= new SwPaM( *(SwPaM
*)pOrigRg
); // die Suchregion ist vorgegeben
615 // sorge dafuer, dass SPoint auf dem "echten" StartPunkt steht
616 // FORWARD --> SPoint immer kleiner als GetMark
617 // BACKWARD --> SPoint immer groesser als GetMark
618 if( (pPam
->GetMark()->*fnMove
->fnCmpOp
)( *pPam
->GetPoint() ) )
624 SwPaM
& SwPaM::Normalize(BOOL bPointFirst
)
627 if ( ( bPointFirst
&& *m_pPoint
> *m_pMark
) ||
628 (!bPointFirst
&& *m_pPoint
< *m_pMark
) )
636 USHORT
SwPaM::GetPageNum( BOOL bAtPoint
, const Point
* pLayPos
)
638 // return die Seitennummer am Cursor
639 // (fuer Reader + Seitengebundene Rahmen)
640 const SwCntntFrm
* pCFrm
;
641 const SwPageFrm
*pPg
;
642 const SwCntntNode
*pNd
;
643 const SwPosition
* pPos
= bAtPoint
? m_pPoint
: m_pMark
;
645 if( 0 != ( pNd
= pPos
->nNode
.GetNode().GetCntntNode() ) &&
646 0 != ( pCFrm
= pNd
->GetFrm( pLayPos
, pPos
, FALSE
)) &&
647 0 != ( pPg
= pCFrm
->FindPageFrm() ))
648 return pPg
->GetPhyPageNum();
652 // --> FME 2004-06-29 #114856# Formular view
653 // See also SwCrsrShell::IsCrsrReadonly()
654 const SwFrm
* lcl_FindEditInReadonlyFrm( const SwFrm
& rFrm
)
656 const SwFrm
* pRet
= 0;
658 const SwFlyFrm
* pFly
;
659 const SwSectionFrm
* pSectionFrm
;
661 if( rFrm
.IsInFly() &&
662 (pFly
= rFrm
.FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
664 !pFly
->Lower()->IsNoTxtFrm() )
668 else if ( rFrm
.IsInSct() &&
669 0 != ( pSectionFrm
= rFrm
.FindSctFrm() )->GetSection() &&
670 pSectionFrm
->GetSection()->IsEditInReadonlyFlag() )
679 // steht in etwas geschuetztem oder in die Selektion umspannt
680 // etwas geschuetztes.
681 BOOL
SwPaM::HasReadonlySel( bool bFormView
) const
685 const SwCntntNode
*pNd
;
686 const SwCntntFrm
*pFrm
;
688 if( 0 != ( pNd
= GetPoint()->nNode
.GetNode().GetCntntNode() ))
689 pFrm
= pNd
->GetFrm( &aTmpPt
, GetPoint(), FALSE
);
693 // --> FME 2004-06-29 #114856# Formular view
694 // Will be set if point/mark are inside edit-in-readonly environment
695 const SwFrm
* pSttEIRFrm
= 0;
696 const SwFrm
* pEndEIRFrm
= 0;
698 if( pFrm
&& ( pFrm
->IsProtected() ||
699 // --> FME 2004-06-29 #114856# Formular view
701 0 == ( pSttEIRFrm
= lcl_FindEditInReadonlyFrm( *pFrm
) ) ) ) )
706 const SwSectionNode
* pSNd
= pNd
->GetSectionNode();
707 if( pSNd
&& ( pSNd
->GetSection().IsProtectFlag() ||
708 // --> FME 2004-06-29 #114856# Formular view
709 (bFormView
&& !pSNd
->GetSection().IsEditInReadonlyFlag()) ) )
714 if( !bRet
&& HasMark() && GetPoint()->nNode
!= GetMark()->nNode
)
716 if( 0 != ( pNd
= GetMark()->nNode
.GetNode().GetCntntNode() ))
717 pFrm
= pNd
->GetFrm( &aTmpPt
, GetMark(), FALSE
);
721 if( pFrm
&& ( pFrm
->IsProtected() ||
722 // --> FME 2004-06-29 #114856# Formular view
724 0 == ( pEndEIRFrm
= lcl_FindEditInReadonlyFrm( *pFrm
) ) ) ) )
729 const SwSectionNode
* pSNd
= pNd
->GetSectionNode();
730 if( pSNd
&& ( pSNd
->GetSection().IsProtectFlag() ||
731 // --> FME 2004-06-29 #114856# Formular view
732 (bFormView
&& !pSNd
->GetSection().IsEditInReadonlyFlag()) ) )
737 // --> FME 2004-06-29 #114856# Formular view
738 if ( !bRet
&& bFormView
)
740 // Check if start and end frame are inside the _same_
741 // edit-in-readonly-environment. Otherwise we better return 'true'
742 if ( pSttEIRFrm
!= pEndEIRFrm
)
747 // oder sollte eine geschuetzte Section innerhalb der
751 ULONG nSttIdx
= GetMark()->nNode
.GetIndex(),
752 nEndIdx
= GetPoint()->nNode
.GetIndex();
753 if( nEndIdx
<= nSttIdx
)
755 ULONG nTmp
= nSttIdx
;
760 // wenn ein geschuetzter Bereich zwischen den Nodes stehen soll,
761 // muss die Selektion selbst schon x Nodes umfassen.
762 // (TxtNd, SectNd, TxtNd, EndNd, TxtNd )
763 if( nSttIdx
+ 3 < nEndIdx
)
765 const SwSectionFmts
& rFmts
= GetDoc()->GetSections();
766 for( USHORT n
= rFmts
.Count(); n
; )
768 const SwSectionFmt
* pFmt
= rFmts
[ --n
];
769 if( pFmt
->GetProtect().IsCntntProtected() )
771 const SwFmtCntnt
& rCntnt
= pFmt
->GetCntnt(FALSE
);
772 ASSERT( rCntnt
.GetCntntIdx(), "wo ist der SectionNode?" );
773 ULONG nIdx
= rCntnt
.GetCntntIdx()->GetIndex();
774 if( nSttIdx
<= nIdx
&& nEndIdx
>= nIdx
&&
775 rCntnt
.GetCntntIdx()->GetNode().GetNodes().IsDocNodes() )
777 /* // ist es keine gelinkte Section, dann kann sie auch
778 // nicht mitselektiert werden
779 const SwSection& rSect = *pFmt->GetSection();
780 if( CONTENT_SECTION == rSect.GetType() )
792 #ifdef CHECK_CELL_READONLY
793 //JP 22.01.99: bisher wurden Tabelle, die in der Text-Selektion standen
794 // nicht beachtet. Wollte man das haben, dann muss dieser
795 // Code freigeschaltet werden
799 // dann noch ueber alle Tabellen
800 const SwFrmFmts
& rFmts
= *GetDoc()->GetTblFrmFmts();
801 for( n
= rFmts
.Count(); n
; )
803 SwFrmFmt
* pFmt
= (SwFrmFmt
*)rFmts
[ --n
];
804 const SwTable
* pTbl
= SwTable::FindTable( pFmt
);
805 ULONG nIdx
= pTbl
? pTbl
->GetTabSortBoxes()[0]->GetSttIdx()
807 if( nSttIdx
<= nIdx
&& nEndIdx
>= nIdx
)
809 // dann teste mal alle Boxen
810 const SwTableSortBoxes
& rBoxes
= pTbl
->GetTabSortBoxes();
812 for( USHORT i
= rBoxes
.Count(); i
; )
813 if( rBoxes
[ --i
]->GetFrmFmt()->GetProtect().
830 // TODO: Form Protection when Enhanced Fields are enabled
832 const SwDoc
*pDoc
= GetDoc();
833 sw::mark::IMark
* pA
= NULL
;
834 sw::mark::IMark
* pB
= NULL
;
837 const IDocumentMarkAccess
* pMarksAccess
= pDoc
->getIDocumentMarkAccess( );
838 pA
= GetPoint() ? pMarksAccess
->getFieldmarkFor( *GetPoint( ) ) : NULL
;
839 pB
= GetMark( ) ? pMarksAccess
->getFieldmarkFor( *GetMark( ) ) : pA
;
842 bool bProtectForm
= pDoc
->get( IDocumentSettingAccess::PROTECT_FORM
);
844 bRet
|= ( pA
== NULL
|| pB
== NULL
);
849 //-------------------- Suche nach Formaten( FormatNamen ) -----------------
851 // die Funktion gibt in Suchrichtung den folgenden Node zurueck.
852 // Ist in der Richtung keiner mehr vorhanden oder ist dieser ausserhalb
853 // des Bereiches, wird ein 0 Pointer returnt.
854 // Das rbFirst gibt an, ob es man zu erstenmal einen Node holt. Ist das der
855 // Fall, darf die Position vom Pam nicht veraendert werden!
858 SwCntntNode
* GetNode( SwPaM
& rPam
, BOOL
& rbFirst
, SwMoveFn fnMove
,
861 SwCntntNode
* pNd
= 0;
863 if( ((*rPam
.GetPoint()).*fnMove
->fnCmpOp
)( *rPam
.GetMark() ) ||
864 ( *rPam
.GetPoint() == *rPam
.GetMark() && rbFirst
) )
869 pNd
= rPam
.GetCntntNode();
874 0 == ( pFrm
= pNd
->GetFrm()) ||
875 ( !bInReadOnly
&& pFrm
->IsProtected() ) ||
876 (pFrm
->IsTxtFrm() && ((SwTxtFrm
*)pFrm
)->IsHiddenNow())
878 ( !bInReadOnly
&& pNd
->FindSectionNode() &&
879 pNd
->FindSectionNode()->GetSection().IsProtect()
888 if( !pNd
) // steht Cursor auf keinem ContentNode ?
890 SwPosition
aPos( *rPam
.GetPoint() );
891 BOOL bSrchForward
= fnMove
== fnMoveForward
;
892 SwNodes
& rNodes
= aPos
.nNode
.GetNodes();
894 // zum naechsten / vorherigen ContentNode
895 // Funktioniert noch alles, wenn die Uerbpruefung vom ueberspringen der
896 // Sektions herausgenommen wird ??
897 // if( (*fnMove->fnNds)( rNodes, &aPos.nNode ) )
901 ? rNodes
.GoNextSection( &aPos
.nNode
, TRUE
, !bInReadOnly
)
902 : rNodes
.GoPrevSection( &aPos
.nNode
, TRUE
, !bInReadOnly
);
905 aPos
.nContent
.Assign( pNd
, ::GetSttOrEnd( bSrchForward
,*pNd
));
906 // liegt Position immer noch im Bereich ?
907 if( (aPos
.*fnMove
->fnCmpOp
)( *rPam
.GetMark() ) )
909 // nur in der AutoTextSection koennen Node stehen, die
910 // nicht angezeigt werden !!
911 if( 0 == ( pFrm
= pNd
->GetFrm()) ||
912 ( !bInReadOnly
&& pFrm
->IsProtected() ) ||
913 ( pFrm
->IsTxtFrm() &&
914 ((SwTxtFrm
*)pFrm
)->IsHiddenNow() ) )
916 // rNodes[ rNodes.EndOfAutotext ]->StartOfSection().GetIndex()
917 // < aPos.nNode.GetIndex() && aPos.nNode.GetIndex()
918 // < rNodes.EndOfAutotext.GetIndex() &&
919 // 0 == ( pFrm = pNd->GetFrm()) &&
920 // pFrm->IsProtected() )
923 continue; // suche weiter
925 *(SwPosition
*)rPam
.GetPoint() = aPos
;
928 pNd
= 0; // kein gueltiger Node
938 // ----------------------------------------------------------------------
940 // hier folgen die Move-Methoden ( Foward, Backward; Content, Node, Doc )
943 void GoStartDoc( SwPosition
* pPos
)
945 SwNodes
& rNodes
= pPos
->nNode
.GetNodes();
946 pPos
->nNode
= *rNodes
.GetEndOfContent().StartOfSectionNode();
947 // es muss immer ein ContentNode gefunden werden !!
948 SwCntntNode
* pCNd
= rNodes
.GoNext( &pPos
->nNode
);
950 pCNd
->MakeStartIndex( &pPos
->nContent
);
954 void GoEndDoc( SwPosition
* pPos
)
956 SwNodes
& rNodes
= pPos
->nNode
.GetNodes();
957 pPos
->nNode
= rNodes
.GetEndOfContent();
958 SwCntntNode
* pCNd
= GoPreviousNds( &pPos
->nNode
, TRUE
);
960 pCNd
->MakeEndIndex( &pPos
->nContent
);
964 void GoStartSection( SwPosition
* pPos
)
966 // springe zum Anfang der Section
967 SwNodes
& rNodes
= pPos
->nNode
.GetNodes();
968 USHORT nLevel
= rNodes
.GetSectionLevel( pPos
->nNode
);
969 if( pPos
->nNode
< rNodes
.GetEndOfContent().StartOfSectionIndex() )
971 do { rNodes
.GoStartOfSection( &pPos
->nNode
); } while( nLevel
-- );
973 // steht jetzt schon auf einem CntntNode
974 pPos
->nNode
.GetNode().GetCntntNode()->MakeStartIndex( &pPos
->nContent
);
977 // gehe an das Ende der akt. Grund-Section
980 void GoEndSection( SwPosition
* pPos
)
982 // springe zum Anfang/Ende der Section
983 SwNodes
& rNodes
= pPos
->nNode
.GetNodes();
984 USHORT nLevel
= rNodes
.GetSectionLevel( pPos
->nNode
);
985 if( pPos
->nNode
< rNodes
.GetEndOfContent().StartOfSectionIndex() )
987 do { rNodes
.GoEndOfSection( &pPos
->nNode
); } while( nLevel
-- );
989 // steht jetzt auf einem EndNode, also zum vorherigen CntntNode
990 if( GoPreviousNds( &pPos
->nNode
, TRUE
) )
991 pPos
->nNode
.GetNode().GetCntntNode()->MakeEndIndex( &pPos
->nContent
);
996 BOOL
GoInDoc( SwPaM
& rPam
, SwMoveFn fnMove
)
998 (*fnMove
->fnDoc
)( rPam
.GetPoint() );
1003 BOOL
GoInSection( SwPaM
& rPam
, SwMoveFn fnMove
)
1005 (*fnMove
->fnSections
)( (SwPosition
*)rPam
.GetPoint() );
1010 BOOL
GoInNode( SwPaM
& rPam
, SwMoveFn fnMove
)
1012 SwCntntNode
*pNd
= (*fnMove
->fnNds
)( &rPam
.GetPoint()->nNode
, TRUE
);
1014 rPam
.GetPoint()->nContent
.Assign( pNd
,
1015 ::GetSttOrEnd( fnMove
== fnMoveForward
, *pNd
) );
1020 BOOL
GoInCntnt( SwPaM
& rPam
, SwMoveFn fnMove
)
1022 if( (*fnMove
->fnNd
)( &rPam
.GetPoint()->nNode
.GetNode(),
1023 &rPam
.GetPoint()->nContent
, CRSR_SKIP_CHARS
))
1025 return GoInNode( rPam
, fnMove
);
1028 BOOL
GoInCntntCells( SwPaM
& rPam
, SwMoveFn fnMove
)
1030 if( (*fnMove
->fnNd
)( &rPam
.GetPoint()->nNode
.GetNode(),
1031 &rPam
.GetPoint()->nContent
, CRSR_SKIP_CELLS
))
1033 return GoInNode( rPam
, fnMove
);
1036 BOOL
GoInCntntSkipHidden( SwPaM
& rPam
, SwMoveFn fnMove
)
1038 if( (*fnMove
->fnNd
)( &rPam
.GetPoint()->nNode
.GetNode(),
1039 &rPam
.GetPoint()->nContent
, CRSR_SKIP_CHARS
| CRSR_SKIP_HIDDEN
) )
1041 return GoInNode( rPam
, fnMove
);
1044 BOOL
GoInCntntCellsSkipHidden( SwPaM
& rPam
, SwMoveFn fnMove
)
1046 if( (*fnMove
->fnNd
)( &rPam
.GetPoint()->nNode
.GetNode(),
1047 &rPam
.GetPoint()->nContent
, CRSR_SKIP_CELLS
| CRSR_SKIP_HIDDEN
) )
1049 return GoInNode( rPam
, fnMove
);
1054 // --------- Funktionsdefinitionen fuer die SwCrsrShell --------------
1057 BOOL
GoPrevPara( SwPaM
& rPam
, SwPosPara aPosPara
)
1059 if( rPam
.Move( fnMoveBackward
, fnGoNode
) )
1061 // steht immer auf einem ContentNode !
1062 SwPosition
& rPos
= *rPam
.GetPoint();
1063 SwCntntNode
* pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1064 rPos
.nContent
.Assign( pNd
,
1065 ::GetSttOrEnd( aPosPara
== fnMoveForward
, *pNd
) );
1072 BOOL
GoCurrPara( SwPaM
& rPam
, SwPosPara aPosPara
)
1074 SwPosition
& rPos
= *rPam
.GetPoint();
1075 SwCntntNode
* pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1078 xub_StrLen nOld
= rPos
.nContent
.GetIndex(),
1079 nNew
= aPosPara
== fnMoveForward
? 0 : pNd
->Len();
1080 // stand er schon auf dem Anfang/Ende dann zum naechsten/vorherigen
1083 rPos
.nContent
.Assign( pNd
, nNew
);
1087 // den Node noch etwas bewegen ( auf den naechsten/vorh. CntntNode)
1088 if( ( aPosPara
==fnParaStart
&& 0 != ( pNd
=
1089 GoPreviousNds( &rPos
.nNode
, TRUE
))) ||
1090 ( aPosPara
==fnParaEnd
&& 0 != ( pNd
=
1091 GoNextNds( &rPos
.nNode
, TRUE
))) )
1093 rPos
.nContent
.Assign( pNd
,
1094 ::GetSttOrEnd( aPosPara
== fnMoveForward
, *pNd
));
1101 BOOL
GoNextPara( SwPaM
& rPam
, SwPosPara aPosPara
)
1103 if( rPam
.Move( fnMoveForward
, fnGoNode
) )
1105 // steht immer auf einem ContentNode !
1106 SwPosition
& rPos
= *rPam
.GetPoint();
1107 SwCntntNode
* pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1108 rPos
.nContent
.Assign( pNd
,
1109 ::GetSttOrEnd( aPosPara
== fnMoveForward
, *pNd
) );
1117 BOOL
GoCurrSection( SwPaM
& rPam
, SwMoveFn fnMove
)
1119 SwPosition
& rPos
= *rPam
.GetPoint();
1120 SwPosition
aSavePos( rPos
); // eine Vergleichsposition
1121 SwNodes
& rNds
= aSavePos
.nNode
.GetNodes();
1122 (rNds
.*fnMove
->fnSection
)( &rPos
.nNode
);
1124 if( 0 == ( pNd
= rPos
.nNode
.GetNode().GetCntntNode()) &&
1125 0 == ( pNd
= (*fnMove
->fnNds
)( &rPos
.nNode
, TRUE
)) )
1127 rPos
= aSavePos
; // Cusror nicht veraendern
1131 rPos
.nContent
.Assign( pNd
,
1132 ::GetSttOrEnd( fnMove
== fnMoveForward
, *pNd
) );
1133 return aSavePos
!= rPos
;
1137 BOOL
GoNextSection( SwPaM
& rPam
, SwMoveFn fnMove
)
1139 SwPosition
& rPos
= *rPam
.GetPoint();
1140 SwPosition
aSavePos( rPos
); // eine Vergleichsposition
1141 SwNodes
& rNds
= aSavePos
.nNode
.GetNodes();
1142 rNds
.GoEndOfSection( &rPos
.nNode
);
1144 // kein weiterer ContentNode vorhanden ?
1145 if( !GoInCntnt( rPam
, fnMoveForward
) )
1147 rPos
= aSavePos
; // Cusror nicht veraendern
1150 (rNds
.*fnMove
->fnSection
)( &rPos
.nNode
);
1151 SwCntntNode
*pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1152 rPos
.nContent
.Assign( pNd
,
1153 ::GetSttOrEnd( fnMove
== fnMoveForward
, *pNd
) );
1158 BOOL
GoPrevSection( SwPaM
& rPam
, SwMoveFn fnMove
)
1160 SwPosition
& rPos
= *rPam
.GetPoint();
1161 SwPosition
aSavePos( rPos
); // eine Vergleichsposition
1162 SwNodes
& rNds
= aSavePos
.nNode
.GetNodes();
1163 rNds
.GoStartOfSection( &rPos
.nNode
);
1165 // kein weiterer ContentNode vorhanden ?
1166 if( !GoInCntnt( rPam
, fnMoveBackward
))
1168 rPos
= aSavePos
; // Cusror nicht veraendern
1171 (rNds
.*fnMove
->fnSection
)( &rPos
.nNode
);
1172 SwCntntNode
*pNd
= rPos
.nNode
.GetNode().GetCntntNode();
1173 rPos
.nContent
.Assign( pNd
,
1174 ::GetSttOrEnd( fnMove
== fnMoveForward
, *pNd
));
1179 String
SwPaM::GetTxt() const
1183 SwNodeIndex aNodeIndex
= Start()->nNode
;
1185 /* The first node can be the end node. A first end node must be
1186 handled, too. There fore do ... while and no incrementing of
1187 aNodeIndex in the first pass.
1199 SwTxtNode
* pTxtNode
= aNodeIndex
.GetNode().GetTxtNode();
1201 if (pTxtNode
!= NULL
)
1203 const String
& aTmpStr
= pTxtNode
->GetTxt();
1205 if (aNodeIndex
== Start()->nNode
)
1208 if (End()->nNode
== aNodeIndex
)
1209 nEnd
= End()->nContent
.GetIndex();
1211 nEnd
= aTmpStr
.Len();
1213 aResult
+= aTmpStr
.Copy(Start()->nContent
.GetIndex(),
1214 nEnd
- Start()->nContent
.GetIndex()) ;
1216 else if (aNodeIndex
== End()->nNode
)
1217 aResult
+= aTmpStr
.Copy(0, End()->nContent
.GetIndex());
1222 while (aNodeIndex
!= End()->nNode
);
1227 BOOL
SwPaM::Overlap(const SwPaM
& a
, const SwPaM
& b
)
1229 return !(*b
.End() <= *a
.Start() || *a
.End() <= *b
.End());
1232 void SwPaM::Invalidate()
1234 const SwNode
*_pNd
=this->GetNode();
1235 const SwTxtNode
*_pTxtNd
=(_pNd
!=NULL
?_pNd
->GetTxtNode():NULL
);
1236 if (_pTxtNd
!=NULL
) {
1237 //pretent we've added a char to force layout to recalc the portion...
1238 SwInsChr
aHint(_pTxtNd
->GetIndex());
1239 SwModify
*_pModify
=(SwModify
*)_pTxtNd
;
1240 _pModify
->Modify( 0, &aHint
);
1244 BOOL
SwPaM::LessThan(const SwPaM
& a
, const SwPaM
& b
)
1246 return (*a
.Start() < *b
.Start()) || (*a
.Start() == *b
.Start() && *a
.End() < *b
.End());