summaryrefslogtreecommitdiff
path: root/sw/source/core/crsr/pam.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/crsr/pam.cxx')
-rw-r--r--sw/source/core/crsr/pam.cxx1246
1 files changed, 1246 insertions, 0 deletions
diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx
new file mode 100644
index 000000000000..ec30b5aefbe0
--- /dev/null
+++ b/sw/source/core/crsr/pam.cxx
@@ -0,0 +1,1246 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+#include <hintids.hxx>
+#include <editeng/protitem.hxx>
+#include <cntfrm.hxx>
+#include <pagefrm.hxx>
+#include <doc.hxx>
+#include <docary.hxx>
+#include <pam.hxx>
+#include <pamtyp.hxx>
+#include <txtfrm.hxx>
+#include <section.hxx>
+#include <fmtcntnt.hxx>
+#include <frmatr.hxx>
+#include <swtable.hxx>
+#include <crsskip.hxx>
+
+// --> FME 2004-06-29 #114856# Formular view
+#include <flyfrm.hxx>
+#include <fmteiro.hxx>
+#include <section.hxx>
+#include <sectfrm.hxx>
+// <--
+#include <ndtxt.hxx> // #111827#
+
+#include <IMark.hxx>
+#include <hints.hxx>
+
+// fuer den dummen ?MSC-? Compiler
+inline xub_StrLen GetSttOrEnd( BOOL bCondition, const SwCntntNode& rNd )
+{
+ return bCondition ? 0 : rNd.Len();
+}
+
+/*************************************************************************
+|*
+|* SwPosition
+|*
+|* Beschreibung PAM.DOC
+|* Ersterstellung VB 4.3.91
+|* Letzte Aenderung VB 4.3.91
+|*
+*************************************************************************/
+
+
+SwPosition::SwPosition( const SwNodeIndex & rNodeIndex, const SwIndex & rCntnt )
+ : nNode( rNodeIndex ), nContent( rCntnt )
+{
+}
+
+SwPosition::SwPosition( const SwNodeIndex & rNodeIndex )
+ : nNode( rNodeIndex ), nContent( nNode.GetNode().GetCntntNode() )
+{
+}
+
+SwPosition::SwPosition( const SwNode& rNode )
+ : nNode( rNode ), nContent( nNode.GetNode().GetCntntNode() )
+{
+}
+
+SwPosition::SwPosition( SwCntntNode & rNode, const xub_StrLen nOffset )
+ : nNode( rNode ), nContent( &rNode, nOffset )
+{
+}
+
+
+SwPosition::SwPosition( const SwPosition & rPos )
+ : nNode( rPos.nNode ), nContent( rPos.nContent )
+{
+}
+
+SwPosition &SwPosition::operator=(const SwPosition &rPos)
+{
+ nNode = rPos.nNode;
+ nContent = rPos.nContent;
+ return *this;
+}
+
+
+BOOL SwPosition::operator<(const SwPosition &rPos) const
+{
+ if( nNode < rPos.nNode )
+ return TRUE;
+ if( nNode == rPos.nNode )
+ return ( nContent < rPos.nContent );
+ return FALSE;
+}
+
+
+BOOL SwPosition::operator>(const SwPosition &rPos) const
+{
+ if(nNode > rPos.nNode )
+ return TRUE;
+ if( nNode == rPos.nNode )
+ return ( nContent > rPos.nContent );
+ return FALSE;
+}
+
+
+BOOL SwPosition::operator<=(const SwPosition &rPos) const
+{
+ if(nNode < rPos.nNode )
+ return TRUE;
+ if( nNode == rPos.nNode )
+ return ( nContent <= rPos.nContent );
+ return FALSE;
+}
+
+
+BOOL SwPosition::operator>=(const SwPosition &rPos) const
+{
+ if(nNode > rPos.nNode )
+ return TRUE;
+ if( nNode == rPos.nNode )
+ return ( nContent >= rPos.nContent );
+ return FALSE;
+}
+
+
+BOOL SwPosition::operator==(const SwPosition &rPos) const
+{
+ return
+ ( ( nNode == rPos.nNode ) && ( nContent == rPos.nContent ) ?
+ TRUE: FALSE);
+}
+
+
+BOOL SwPosition::operator!=(const SwPosition &rPos) const
+{
+ if( nNode != rPos.nNode )
+ return TRUE;
+ return ( nContent != rPos.nContent );
+}
+
+SwDoc * SwPosition::GetDoc() const
+{
+ return nNode.GetNode().GetDoc();
+}
+
+SwComparePosition ComparePosition(
+ const SwPosition& rStt1, const SwPosition& rEnd1,
+ const SwPosition& rStt2, const SwPosition& rEnd2 )
+{
+ SwComparePosition nRet;
+ if( rStt1 < rStt2 )
+ {
+ if( rEnd1 > rStt2 )
+ {
+ if( rEnd1 >= rEnd2 )
+ nRet = POS_OUTSIDE;
+ else
+ nRet = POS_OVERLAP_BEFORE;
+
+ }
+ else if( rEnd1 == rStt2 )
+ nRet = POS_COLLIDE_END;
+ else
+ nRet = POS_BEFORE;
+ }
+ else if( rEnd2 > rStt1 )
+ {
+ if( rEnd2 >= rEnd1 )
+ {
+ if( rEnd2 == rEnd1 && rStt2 == rStt1 )
+ nRet = POS_EQUAL;
+ else
+ nRet = POS_INSIDE;
+ }
+ else
+ {
+ if (rStt1 == rStt2)
+ nRet = POS_OUTSIDE;
+ else
+ nRet = POS_OVERLAP_BEHIND;
+ }
+ }
+ else if( rEnd2 == rStt1 )
+ nRet = POS_COLLIDE_START;
+ else
+ nRet = POS_BEHIND;
+ return nRet;
+}
+
+SwComparePosition ComparePosition(
+ const unsigned long nStt1, const unsigned long nEnd1,
+ const unsigned long nStt2, const unsigned long nEnd2 )
+{
+ SwComparePosition nRet;
+ if( nStt1 < nStt2 )
+ {
+ if( nEnd1 > nStt2 )
+ {
+ if( nEnd1 >= nEnd2 )
+ nRet = POS_OUTSIDE;
+ else
+ nRet = POS_OVERLAP_BEFORE;
+
+ }
+ else if( nEnd1 == nStt2 )
+ nRet = POS_COLLIDE_END;
+ else
+ nRet = POS_BEFORE;
+ }
+ else if( nEnd2 > nStt1 )
+ {
+ if( nEnd2 >= nEnd1 )
+ {
+ if( nEnd2 == nEnd1 && nStt2 == nStt1 )
+ nRet = POS_EQUAL;
+ else
+ nRet = POS_INSIDE;
+ }
+ else
+ {
+ if (nStt1 == nStt2)
+ nRet = POS_OUTSIDE;
+ else
+ nRet = POS_OVERLAP_BEHIND;
+ }
+ }
+ else if( nEnd2 == nStt1 )
+ nRet = POS_COLLIDE_START;
+ else
+ nRet = POS_BEHIND;
+ return nRet;
+}
+
+/* */
+
+enum CHKSECTION { Chk_Both, Chk_One, Chk_None };
+
+
+CHKSECTION lcl_TstIdx( ULONG nSttIdx, ULONG nEndIdx, const SwNode& rEndNd )
+{
+ ULONG nStt = rEndNd.StartOfSectionIndex(), nEnd = rEndNd.GetIndex();
+ CHKSECTION eSec = nStt < nSttIdx && nEnd >= nSttIdx ? Chk_One : Chk_None;
+ if( nStt < nEndIdx && nEnd >= nEndIdx )
+ return( eSec == Chk_One ? Chk_Both : Chk_One );
+ return eSec;
+}
+
+
+BOOL lcl_ChkOneRange( CHKSECTION eSec, BOOL bChkSections,
+ const SwNode& rBaseEnd, ULONG nStt, ULONG nEnd )
+{
+ if( eSec != Chk_Both )
+ return FALSE;
+
+ if( !bChkSections )
+ return TRUE;
+
+ // suche die umspannende Section
+ const SwNodes& rNds = rBaseEnd.GetNodes();
+ const SwNode *pTmp, *pNd = rNds[ nStt ];
+ if( !pNd->IsStartNode() )
+ pNd = pNd->StartOfSectionNode();
+
+ if( pNd == rNds[ nEnd ]->StartOfSectionNode() )
+ return TRUE; // der gleiche StartNode, die selbe Section
+
+ // steht schon auf einem GrundSection Node ? Fehler !!!
+ if( !pNd->StartOfSectionIndex() )
+ return FALSE;
+
+ while( ( pTmp = pNd->StartOfSectionNode())->EndOfSectionNode() !=
+ &rBaseEnd )
+ pNd = pTmp;
+
+ ULONG nSttIdx = pNd->GetIndex(), nEndIdx = pNd->EndOfSectionIndex();
+ return nSttIdx <= nStt && nStt <= nEndIdx &&
+ nSttIdx <= nEnd && nEnd <= nEndIdx ? TRUE : FALSE;
+}
+
+
+BOOL CheckNodesRange( const SwNodeIndex& rStt,
+ const SwNodeIndex& rEnd, BOOL bChkSection )
+{
+ const SwNodes& rNds = rStt.GetNodes();
+ ULONG nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
+ CHKSECTION eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfContent() );
+ if( Chk_None != eSec ) return eSec == Chk_Both ? TRUE : FALSE;
+
+ eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfAutotext() );
+ if( Chk_None != eSec )
+ return lcl_ChkOneRange( eSec, bChkSection,
+ rNds.GetEndOfAutotext(), nStt, nEnd );
+
+ eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfPostIts() );
+ if( Chk_None != eSec )
+ return lcl_ChkOneRange( eSec, bChkSection,
+ rNds.GetEndOfPostIts(), nStt, nEnd );
+
+ eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfInserts() );
+ if( Chk_None != eSec )
+ return lcl_ChkOneRange( eSec, bChkSection,
+ rNds.GetEndOfInserts(), nStt, nEnd );
+
+ eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfRedlines() );
+ if( Chk_None != eSec )
+ return lcl_ChkOneRange( eSec, bChkSection,
+ rNds.GetEndOfRedlines(), nStt, nEnd );
+
+ return FALSE; // liegt irgendwo dazwischen, FEHLER
+}
+
+
+BOOL GoNext(SwNode* pNd, SwIndex * pIdx, USHORT nMode )
+{
+ if( pNd->IsCntntNode() )
+ return ((SwCntntNode*)pNd)->GoNext( pIdx, nMode );
+ return FALSE;
+}
+
+
+BOOL GoPrevious( SwNode* pNd, SwIndex * pIdx, USHORT nMode )
+{
+ if( pNd->IsCntntNode() )
+ return ((SwCntntNode*)pNd)->GoPrevious( pIdx, nMode );
+ return FALSE;
+}
+
+
+SwCntntNode* GoNextNds( SwNodeIndex* pIdx, BOOL bChk )
+{
+ SwNodeIndex aIdx( *pIdx );
+ SwCntntNode* pNd = aIdx.GetNodes().GoNext( &aIdx );
+ if( pNd )
+ {
+ if( bChk && 1 != aIdx.GetIndex() - pIdx->GetIndex() &&
+ !CheckNodesRange( *pIdx, aIdx, TRUE ) )
+ pNd = 0;
+ else
+ *pIdx = aIdx;
+ }
+ return pNd;
+}
+
+
+SwCntntNode* GoPreviousNds( SwNodeIndex * pIdx, BOOL bChk )
+{
+ SwNodeIndex aIdx( *pIdx );
+ SwCntntNode* pNd = aIdx.GetNodes().GoPrevious( &aIdx );
+ if( pNd )
+ {
+ if( bChk && 1 != pIdx->GetIndex() - aIdx.GetIndex() &&
+ !CheckNodesRange( *pIdx, aIdx, TRUE ) )
+ pNd = 0;
+ else
+ *pIdx = aIdx;
+ }
+ return pNd;
+}
+
+// ----------------------------------------------------------------------
+
+/*************************************************************************
+|*
+|* SwPointAndMark
+|*
+|* Beschreibung PAM.DOC
+|* Ersterstellung VB 4.3.91
+|* Letzte Aenderung JP 6.5.91
+|*
+*************************************************************************/
+
+SwPaM::SwPaM( const SwPosition& rPos, SwPaM* pRing )
+ : Ring( pRing )
+ , m_Bound1( rPos )
+ , m_Bound2( rPos.nNode.GetNode().GetNodes() ) // default initialize
+ , m_pPoint( &m_Bound1 )
+ , m_pMark( m_pPoint )
+ , m_bIsInFrontOfLabel( false )
+{
+}
+
+SwPaM::SwPaM( const SwPosition& rMark, const SwPosition& rPoint, SwPaM* pRing )
+ : Ring( pRing )
+ , m_Bound1( rMark )
+ , m_Bound2( rPoint )
+ , m_pPoint( &m_Bound2 )
+ , m_pMark( &m_Bound1 )
+ , m_bIsInFrontOfLabel( false )
+{
+}
+
+SwPaM::SwPaM( const SwNodeIndex& rMark, const SwNodeIndex& rPoint,
+ long nMarkOffset, long nPointOffset, SwPaM* pRing )
+ : Ring( pRing )
+ , m_Bound1( rMark )
+ , m_Bound2( rPoint )
+ , m_pPoint( &m_Bound2 )
+ , m_pMark( &m_Bound1 )
+ , m_bIsInFrontOfLabel( false )
+{
+ if ( nMarkOffset )
+ {
+ m_pMark->nNode += nMarkOffset;
+ }
+ if ( nPointOffset )
+ {
+ m_pPoint->nNode += nPointOffset;
+ }
+
+ m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetCntntNode(), 0 );
+ m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetCntntNode(), 0 );
+}
+
+SwPaM::SwPaM( const SwNode& rMark, const SwNode& rPoint,
+ long nMarkOffset, long nPointOffset, SwPaM* pRing )
+ : Ring( pRing )
+ , m_Bound1( rMark )
+ , m_Bound2( rPoint )
+ , m_pPoint( &m_Bound2 )
+ , m_pMark( &m_Bound1 )
+ , m_bIsInFrontOfLabel( false )
+{
+ if ( nMarkOffset )
+ {
+ m_pMark->nNode += nMarkOffset;
+ }
+ if ( nPointOffset )
+ {
+ m_pPoint->nNode += nPointOffset;
+ }
+
+ m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetCntntNode(), 0 );
+ m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetCntntNode(), 0 );
+}
+
+SwPaM::SwPaM( const SwNodeIndex& rMark , xub_StrLen nMarkCntnt,
+ const SwNodeIndex& rPoint, xub_StrLen nPointCntnt, SwPaM* pRing )
+ : Ring( pRing )
+ , m_Bound1( rMark )
+ , m_Bound2( rPoint )
+ , m_pPoint( &m_Bound2 )
+ , m_pMark( &m_Bound1 )
+ , m_bIsInFrontOfLabel( false )
+{
+ m_pPoint->nContent.Assign( rPoint.GetNode().GetCntntNode(), nPointCntnt);
+ m_pMark ->nContent.Assign( rMark .GetNode().GetCntntNode(), nMarkCntnt );
+}
+
+SwPaM::SwPaM( const SwNode& rMark , xub_StrLen nMarkCntnt,
+ const SwNode& rPoint, xub_StrLen nPointCntnt, SwPaM* pRing )
+ : Ring( pRing )
+ , m_Bound1( rMark )
+ , m_Bound2( rPoint )
+ , m_pPoint( &m_Bound2 )
+ , m_pMark( &m_Bound1 )
+ , m_bIsInFrontOfLabel( false )
+{
+ m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetCntntNode(),
+ nPointCntnt);
+ m_pMark ->nContent.Assign( m_pMark ->nNode.GetNode().GetCntntNode(),
+ nMarkCntnt );
+}
+
+SwPaM::SwPaM( const SwNode& rNode, xub_StrLen nCntnt, SwPaM* pRing )
+ : Ring( pRing )
+ , m_Bound1( rNode )
+ , m_Bound2( m_Bound1.nNode.GetNode().GetNodes() ) // default initialize
+ , m_pPoint( &m_Bound1 )
+ , m_pMark( &m_Bound1 )
+ , m_bIsInFrontOfLabel( false )
+{
+ m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetCntntNode(),
+ nCntnt );
+}
+
+SwPaM::SwPaM( const SwNodeIndex& rNodeIdx, xub_StrLen nCntnt, SwPaM* pRing )
+ : Ring( pRing )
+ , m_Bound1( rNodeIdx )
+ , m_Bound2( rNodeIdx.GetNode().GetNodes() ) // default initialize
+ , m_pPoint( &m_Bound1 )
+ , m_pMark( &m_Bound1 )
+ , m_bIsInFrontOfLabel( false )
+{
+ m_pPoint->nContent.Assign( rNodeIdx.GetNode().GetCntntNode(), nCntnt );
+}
+
+SwPaM::~SwPaM() {}
+
+// @@@ semantic: no copy ctor.
+SwPaM::SwPaM( SwPaM &rPam )
+ : Ring( &rPam )
+ , m_Bound1( *(rPam.m_pPoint) )
+ , m_Bound2( *(rPam.m_pMark) )
+ , m_pPoint( &m_Bound1 ), m_pMark( rPam.HasMark() ? &m_Bound2 : m_pPoint )
+ , m_bIsInFrontOfLabel( false )
+{
+}
+
+// @@@ semantic: no copy assignment for super class Ring.
+SwPaM &SwPaM::operator=( const SwPaM &rPam )
+{
+ *m_pPoint = *( rPam.m_pPoint );
+ if ( rPam.HasMark() )
+ {
+ SetMark();
+ *m_pMark = *( rPam.m_pMark );
+ }
+ else
+ {
+ DeleteMark();
+ }
+ return *this;
+}
+
+void SwPaM::SetMark()
+{
+ if (m_pPoint == &m_Bound1)
+ {
+ m_pMark = &m_Bound2;
+ }
+ else
+ {
+ m_pMark = &m_Bound1;
+ }
+ (*m_pMark) = (*m_pPoint);
+}
+
+#ifdef DBG_UTIL
+
+void SwPaM::Exchange()
+{
+ if (m_pPoint != m_pMark)
+ {
+ SwPosition *pTmp = m_pPoint;
+ m_pPoint = m_pMark;
+ m_pMark = pTmp;
+ }
+}
+#endif
+
+// Bewegen des Cursors
+
+
+BOOL SwPaM::Move( SwMoveFn fnMove, SwGoInDoc fnGo )
+{
+ BOOL bRet = (*fnGo)( *this, fnMove );
+
+ m_bIsInFrontOfLabel = false;
+
+ return bRet;
+}
+
+
+/*************************************************************************
+|*
+|* void SwPaM::MakeRegion( SwMoveFn, SwPaM*, const SwPaM* )
+|*
+|* Beschreibung Setzt den 1. SwPaM auf den uebergebenen SwPaM
+|* oder setzt auf den Anfang oder Ende vom Document.
+|* SPoint bleibt auf der Position stehen, GetMark aendert
+|* sich entsprechend !
+|*
+|* Parameter SwDirection gibt an, ob an Anfang / Ende
+|* SwPaM * der zu setzende Bereich
+|* const SwPaM& der enventuell vorgegeben Bereich
+|* Return-Werte SwPaM* der entsprehend neu gesetzte Bereich
+|*
+|* Ersterstellung JP 26.04.91
+|* Letzte Aenderung JP 26.04.91
+|*
+*************************************************************************/
+
+
+SwPaM* SwPaM::MakeRegion( SwMoveFn fnMove, const SwPaM * pOrigRg )
+{
+ SwPaM* pPam;
+ if( pOrigRg == 0 )
+ {
+ pPam = new SwPaM( *m_pPoint );
+ pPam->SetMark(); // setze Anfang fest
+ pPam->Move( fnMove, fnGoSection); // an Anfang / Ende vom Node
+
+ // stelle SPoint wieder auf alte Position, GetMark auf das "Ende"
+ pPam->Exchange();
+ }
+ else
+ {
+ pPam = new SwPaM( *(SwPaM*)pOrigRg ); // die Suchregion ist vorgegeben
+ // sorge dafuer, dass SPoint auf dem "echten" StartPunkt steht
+ // FORWARD --> SPoint immer kleiner als GetMark
+ // BACKWARD --> SPoint immer groesser als GetMark
+ if( (pPam->GetMark()->*fnMove->fnCmpOp)( *pPam->GetPoint() ) )
+ pPam->Exchange();
+ }
+ return pPam;
+}
+
+SwPaM & SwPaM::Normalize(BOOL bPointFirst)
+{
+ if (HasMark())
+ if ( ( bPointFirst && *m_pPoint > *m_pMark) ||
+ (!bPointFirst && *m_pPoint < *m_pMark) )
+ {
+ Exchange();
+ }
+
+ return *this;
+}
+
+USHORT SwPaM::GetPageNum( BOOL bAtPoint, const Point* pLayPos )
+{
+ // return die Seitennummer am Cursor
+ // (fuer Reader + Seitengebundene Rahmen)
+ const SwCntntFrm* pCFrm;
+ const SwPageFrm *pPg;
+ const SwCntntNode *pNd ;
+ const SwPosition* pPos = bAtPoint ? m_pPoint : m_pMark;
+
+ if( 0 != ( pNd = pPos->nNode.GetNode().GetCntntNode() ) &&
+ 0 != ( pCFrm = pNd->GetFrm( pLayPos, pPos, FALSE )) &&
+ 0 != ( pPg = pCFrm->FindPageFrm() ))
+ return pPg->GetPhyPageNum();
+ return 0;
+}
+
+// --> FME 2004-06-29 #114856# Formular view
+// See also SwCrsrShell::IsCrsrReadonly()
+const SwFrm* lcl_FindEditInReadonlyFrm( const SwFrm& rFrm )
+{
+ const SwFrm* pRet = 0;
+
+ const SwFlyFrm* pFly;
+ const SwSectionFrm* pSectionFrm;
+
+ if( rFrm.IsInFly() &&
+ (pFly = rFrm.FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
+ pFly->Lower() &&
+ !pFly->Lower()->IsNoTxtFrm() )
+ {
+ pRet = pFly;
+ }
+ else if ( rFrm.IsInSct() &&
+ 0 != ( pSectionFrm = rFrm.FindSctFrm() )->GetSection() &&
+ pSectionFrm->GetSection()->IsEditInReadonlyFlag() )
+ {
+ pRet = pSectionFrm;
+ }
+
+ return pRet;
+}
+// <--
+
+// steht in etwas geschuetztem oder in die Selektion umspannt
+// etwas geschuetztes.
+BOOL SwPaM::HasReadonlySel( bool bFormView ) const
+{
+ BOOL bRet = FALSE;
+ Point aTmpPt;
+ const SwCntntNode *pNd;
+ const SwCntntFrm *pFrm;
+
+ if( 0 != ( pNd = GetPoint()->nNode.GetNode().GetCntntNode() ))
+ pFrm = pNd->GetFrm( &aTmpPt, GetPoint(), FALSE );
+ else
+ pFrm = 0;
+
+ // --> FME 2004-06-29 #114856# Formular view
+ // Will be set if point/mark are inside edit-in-readonly environment
+ const SwFrm* pSttEIRFrm = 0;
+ const SwFrm* pEndEIRFrm = 0;
+
+ if( pFrm && ( pFrm->IsProtected() ||
+ // --> FME 2004-06-29 #114856# Formular view
+ ( bFormView &&
+ 0 == ( pSttEIRFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
+ // <--
+ bRet = TRUE;
+ else if( pNd )
+ {
+ const SwSectionNode* pSNd = pNd->GetSectionNode();
+ if( pSNd && ( pSNd->GetSection().IsProtectFlag() ||
+ // --> FME 2004-06-29 #114856# Formular view
+ (bFormView && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
+ // <--
+ bRet = TRUE;
+ }
+
+ if( !bRet && HasMark() && GetPoint()->nNode != GetMark()->nNode )
+ {
+ if( 0 != ( pNd = GetMark()->nNode.GetNode().GetCntntNode() ))
+ pFrm = pNd->GetFrm( &aTmpPt, GetMark(), FALSE );
+ else
+ pFrm = 0;
+
+ if( pFrm && ( pFrm->IsProtected() ||
+ // --> FME 2004-06-29 #114856# Formular view
+ ( bFormView &&
+ 0 == ( pEndEIRFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
+ // <--
+ bRet = TRUE;
+ else if( pNd )
+ {
+ const SwSectionNode* pSNd = pNd->GetSectionNode();
+ if( pSNd && ( pSNd->GetSection().IsProtectFlag() ||
+ // --> FME 2004-06-29 #114856# Formular view
+ (bFormView && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
+ // <--
+ bRet = TRUE;
+ }
+
+ // --> FME 2004-06-29 #114856# Formular view
+ if ( !bRet && bFormView )
+ {
+ // Check if start and end frame are inside the _same_
+ // edit-in-readonly-environment. Otherwise we better return 'true'
+ if ( pSttEIRFrm != pEndEIRFrm )
+ bRet = TRUE;
+ }
+ // <--
+
+ // oder sollte eine geschuetzte Section innerhalb der
+ // Selektion liegen?
+ if( !bRet )
+ {
+ ULONG nSttIdx = GetMark()->nNode.GetIndex(),
+ nEndIdx = GetPoint()->nNode.GetIndex();
+ if( nEndIdx <= nSttIdx )
+ {
+ ULONG nTmp = nSttIdx;
+ nSttIdx = nEndIdx;
+ nEndIdx = nTmp;
+ }
+
+ // wenn ein geschuetzter Bereich zwischen den Nodes stehen soll,
+ // muss die Selektion selbst schon x Nodes umfassen.
+ // (TxtNd, SectNd, TxtNd, EndNd, TxtNd )
+ if( nSttIdx + 3 < nEndIdx )
+ {
+ const SwSectionFmts& rFmts = GetDoc()->GetSections();
+ for( USHORT n = rFmts.Count(); n; )
+ {
+ const SwSectionFmt* pFmt = rFmts[ --n ];
+ if( pFmt->GetProtect().IsCntntProtected() )
+ {
+ const SwFmtCntnt& rCntnt = pFmt->GetCntnt(FALSE);
+ ASSERT( rCntnt.GetCntntIdx(), "wo ist der SectionNode?" );
+ ULONG nIdx = rCntnt.GetCntntIdx()->GetIndex();
+ if( nSttIdx <= nIdx && nEndIdx >= nIdx &&
+ rCntnt.GetCntntIdx()->GetNode().GetNodes().IsDocNodes() )
+ {
+/* // ist es keine gelinkte Section, dann kann sie auch
+ // nicht mitselektiert werden
+ const SwSection& rSect = *pFmt->GetSection();
+ if( CONTENT_SECTION == rSect.GetType() )
+ {
+ RestoreSavePos();
+ return TRUE;
+ }
+*/
+ bRet = TRUE;
+ break;
+ }
+ }
+ }
+
+#ifdef CHECK_CELL_READONLY
+//JP 22.01.99: bisher wurden Tabelle, die in der Text-Selektion standen
+// nicht beachtet. Wollte man das haben, dann muss dieser
+// Code freigeschaltet werden
+
+ if( !bRet )
+ {
+ // dann noch ueber alle Tabellen
+ const SwFrmFmts& rFmts = *GetDoc()->GetTblFrmFmts();
+ for( n = rFmts.Count(); n ; )
+ {
+ SwFrmFmt* pFmt = (SwFrmFmt*)rFmts[ --n ];
+ const SwTable* pTbl = SwTable::FindTable( pFmt );
+ ULONG nIdx = pTbl ? pTbl->GetTabSortBoxes()[0]->GetSttIdx()
+ : 0;
+ if( nSttIdx <= nIdx && nEndIdx >= nIdx )
+ {
+ // dann teste mal alle Boxen
+ const SwTableSortBoxes& rBoxes = pTbl->GetTabSortBoxes();
+
+ for( USHORT i = rBoxes.Count(); i; )
+ if( rBoxes[ --i ]->GetFrmFmt()->GetProtect().
+ IsCntntProtected() )
+ {
+ bRet = TRUE;
+ break;
+ }
+
+ if( bRet )
+ break;
+ }
+ }
+ }
+#endif
+ }
+ }
+ }
+ //FIXME FieldBk
+ // TODO: Form Protection when Enhanced Fields are enabled
+ if (!bRet) {
+ const SwDoc *pDoc = GetDoc();
+ sw::mark::IMark* pA = NULL;
+ sw::mark::IMark* pB = NULL;
+ if ( pDoc )
+ {
+ const IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess( );
+ pA = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : NULL;
+ pB = GetMark( ) ? pMarksAccess->getFieldmarkFor( *GetMark( ) ) : pA;
+ bRet = ( pA != pB );
+ }
+ bool bProtectForm = pDoc->get( IDocumentSettingAccess::PROTECT_FORM );
+ if ( bProtectForm )
+ bRet |= ( pA == NULL || pB == NULL );
+ }
+ return bRet;
+}
+
+//-------------------- Suche nach Formaten( FormatNamen ) -----------------
+
+// die Funktion gibt in Suchrichtung den folgenden Node zurueck.
+// Ist in der Richtung keiner mehr vorhanden oder ist dieser ausserhalb
+// des Bereiches, wird ein 0 Pointer returnt.
+// Das rbFirst gibt an, ob es man zu erstenmal einen Node holt. Ist das der
+// Fall, darf die Position vom Pam nicht veraendert werden!
+
+
+SwCntntNode* GetNode( SwPaM & rPam, BOOL& rbFirst, SwMoveFn fnMove,
+ BOOL bInReadOnly )
+{
+ SwCntntNode * pNd = 0;
+ SwCntntFrm* pFrm;
+ if( ((*rPam.GetPoint()).*fnMove->fnCmpOp)( *rPam.GetMark() ) ||
+ ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) )
+ {
+ if( rbFirst )
+ {
+ rbFirst = FALSE;
+ pNd = rPam.GetCntntNode();
+ if( pNd )
+ {
+ if(
+ (
+ 0 == ( pFrm = pNd->GetFrm()) ||
+ ( !bInReadOnly && pFrm->IsProtected() ) ||
+ (pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow())
+ ) ||
+ ( !bInReadOnly && pNd->FindSectionNode() &&
+ pNd->FindSectionNode()->GetSection().IsProtect()
+ )
+ )
+ {
+ pNd = 0;
+ }
+ }
+ }
+
+ if( !pNd ) // steht Cursor auf keinem ContentNode ?
+ {
+ SwPosition aPos( *rPam.GetPoint() );
+ BOOL bSrchForward = fnMove == fnMoveForward;
+ SwNodes& rNodes = aPos.nNode.GetNodes();
+
+ // zum naechsten / vorherigen ContentNode
+// Funktioniert noch alles, wenn die Uerbpruefung vom ueberspringen der
+// Sektions herausgenommen wird ??
+// if( (*fnMove->fnNds)( rNodes, &aPos.nNode ) )
+ while( TRUE )
+ {
+ pNd = bSrchForward
+ ? rNodes.GoNextSection( &aPos.nNode, TRUE, !bInReadOnly )
+ : rNodes.GoPrevSection( &aPos.nNode, TRUE, !bInReadOnly );
+ if( pNd )
+ {
+ aPos.nContent.Assign( pNd, ::GetSttOrEnd( bSrchForward,*pNd ));
+ // liegt Position immer noch im Bereich ?
+ if( (aPos.*fnMove->fnCmpOp)( *rPam.GetMark() ) )
+ {
+ // nur in der AutoTextSection koennen Node stehen, die
+ // nicht angezeigt werden !!
+ if( 0 == ( pFrm = pNd->GetFrm()) ||
+ ( !bInReadOnly && pFrm->IsProtected() ) ||
+ ( pFrm->IsTxtFrm() &&
+ ((SwTxtFrm*)pFrm)->IsHiddenNow() ) )
+
+// rNodes[ rNodes.EndOfAutotext ]->StartOfSection().GetIndex()
+// < aPos.nNode.GetIndex() && aPos.nNode.GetIndex()
+// < rNodes.EndOfAutotext.GetIndex() &&
+// 0 == ( pFrm = pNd->GetFrm()) &&
+// pFrm->IsProtected() )
+ {
+ pNd = 0;
+ continue; // suche weiter
+ }
+ *(SwPosition*)rPam.GetPoint() = aPos;
+ }
+ else
+ pNd = 0; // kein gueltiger Node
+ break;
+ }
+ break;
+ }
+ }
+ }
+ return pNd;
+}
+
+// ----------------------------------------------------------------------
+
+// hier folgen die Move-Methoden ( Foward, Backward; Content, Node, Doc )
+
+
+void GoStartDoc( SwPosition * pPos )
+{
+ SwNodes& rNodes = pPos->nNode.GetNodes();
+ pPos->nNode = *rNodes.GetEndOfContent().StartOfSectionNode();
+ // es muss immer ein ContentNode gefunden werden !!
+ SwCntntNode* pCNd = rNodes.GoNext( &pPos->nNode );
+ if( pCNd )
+ pCNd->MakeStartIndex( &pPos->nContent );
+}
+
+
+void GoEndDoc( SwPosition * pPos )
+{
+ SwNodes& rNodes = pPos->nNode.GetNodes();
+ pPos->nNode = rNodes.GetEndOfContent();
+ SwCntntNode* pCNd = GoPreviousNds( &pPos->nNode, TRUE );
+ if( pCNd )
+ pCNd->MakeEndIndex( &pPos->nContent );
+}
+
+
+void GoStartSection( SwPosition * pPos )
+{
+ // springe zum Anfang der Section
+ SwNodes& rNodes = pPos->nNode.GetNodes();
+ USHORT nLevel = rNodes.GetSectionLevel( pPos->nNode );
+ if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
+ nLevel--;
+ do { rNodes.GoStartOfSection( &pPos->nNode ); } while( nLevel-- );
+
+ // steht jetzt schon auf einem CntntNode
+ pPos->nNode.GetNode().GetCntntNode()->MakeStartIndex( &pPos->nContent );
+}
+
+// gehe an das Ende der akt. Grund-Section
+
+
+void GoEndSection( SwPosition * pPos )
+{
+ // springe zum Anfang/Ende der Section
+ SwNodes& rNodes = pPos->nNode.GetNodes();
+ USHORT nLevel = rNodes.GetSectionLevel( pPos->nNode );
+ if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
+ nLevel--;
+ do { rNodes.GoEndOfSection( &pPos->nNode ); } while( nLevel-- );
+
+ // steht jetzt auf einem EndNode, also zum vorherigen CntntNode
+ if( GoPreviousNds( &pPos->nNode, TRUE ) )
+ pPos->nNode.GetNode().GetCntntNode()->MakeEndIndex( &pPos->nContent );
+}
+
+
+
+BOOL GoInDoc( SwPaM & rPam, SwMoveFn fnMove )
+{
+ (*fnMove->fnDoc)( rPam.GetPoint() );
+ return TRUE;
+}
+
+
+BOOL GoInSection( SwPaM & rPam, SwMoveFn fnMove )
+{
+ (*fnMove->fnSections)( (SwPosition*)rPam.GetPoint() );
+ return TRUE;
+}
+
+
+BOOL GoInNode( SwPaM & rPam, SwMoveFn fnMove )
+{
+ SwCntntNode *pNd = (*fnMove->fnNds)( &rPam.GetPoint()->nNode, TRUE );
+ if( pNd )
+ rPam.GetPoint()->nContent.Assign( pNd,
+ ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
+ return 0 != pNd;
+}
+
+
+BOOL GoInCntnt( SwPaM & rPam, SwMoveFn fnMove )
+{
+ if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
+ &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS ))
+ return TRUE;
+ return GoInNode( rPam, fnMove );
+}
+
+BOOL GoInCntntCells( SwPaM & rPam, SwMoveFn fnMove )
+{
+ if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
+ &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS ))
+ return TRUE;
+ return GoInNode( rPam, fnMove );
+}
+
+BOOL GoInCntntSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
+{
+ if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
+ &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS | CRSR_SKIP_HIDDEN ) )
+ return TRUE;
+ return GoInNode( rPam, fnMove );
+}
+
+BOOL GoInCntntCellsSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
+{
+ if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
+ &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS | CRSR_SKIP_HIDDEN ) )
+ return TRUE;
+ return GoInNode( rPam, fnMove );
+}
+
+
+
+// --------- Funktionsdefinitionen fuer die SwCrsrShell --------------
+
+
+BOOL GoPrevPara( SwPaM & rPam, SwPosPara aPosPara )
+{
+ if( rPam.Move( fnMoveBackward, fnGoNode ) )
+ {
+ // steht immer auf einem ContentNode !
+ SwPosition& rPos = *rPam.GetPoint();
+ SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
+ rPos.nContent.Assign( pNd,
+ ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOL GoCurrPara( SwPaM & rPam, SwPosPara aPosPara )
+{
+ SwPosition& rPos = *rPam.GetPoint();
+ SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
+ if( pNd )
+ {
+ xub_StrLen nOld = rPos.nContent.GetIndex(),
+ nNew = aPosPara == fnMoveForward ? 0 : pNd->Len();
+ // stand er schon auf dem Anfang/Ende dann zum naechsten/vorherigen
+ if( nOld != nNew )
+ {
+ rPos.nContent.Assign( pNd, nNew );
+ return TRUE;
+ }
+ }
+ // den Node noch etwas bewegen ( auf den naechsten/vorh. CntntNode)
+ if( ( aPosPara==fnParaStart && 0 != ( pNd =
+ GoPreviousNds( &rPos.nNode, TRUE ))) ||
+ ( aPosPara==fnParaEnd && 0 != ( pNd =
+ GoNextNds( &rPos.nNode, TRUE ))) )
+ {
+ rPos.nContent.Assign( pNd,
+ ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+BOOL GoNextPara( SwPaM & rPam, SwPosPara aPosPara )
+{
+ if( rPam.Move( fnMoveForward, fnGoNode ) )
+ {
+ // steht immer auf einem ContentNode !
+ SwPosition& rPos = *rPam.GetPoint();
+ SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
+ rPos.nContent.Assign( pNd,
+ ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+
+BOOL GoCurrSection( SwPaM & rPam, SwMoveFn fnMove )
+{
+ SwPosition& rPos = *rPam.GetPoint();
+ SwPosition aSavePos( rPos ); // eine Vergleichsposition
+ SwNodes& rNds = aSavePos.nNode.GetNodes();
+ (rNds.*fnMove->fnSection)( &rPos.nNode );
+ SwCntntNode *pNd;
+ if( 0 == ( pNd = rPos.nNode.GetNode().GetCntntNode()) &&
+ 0 == ( pNd = (*fnMove->fnNds)( &rPos.nNode, TRUE )) )
+ {
+ rPos = aSavePos; // Cusror nicht veraendern
+ return FALSE;
+ }
+
+ rPos.nContent.Assign( pNd,
+ ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
+ return aSavePos != rPos;
+}
+
+
+BOOL GoNextSection( SwPaM & rPam, SwMoveFn fnMove )
+{
+ SwPosition& rPos = *rPam.GetPoint();
+ SwPosition aSavePos( rPos ); // eine Vergleichsposition
+ SwNodes& rNds = aSavePos.nNode.GetNodes();
+ rNds.GoEndOfSection( &rPos.nNode );
+
+ // kein weiterer ContentNode vorhanden ?
+ if( !GoInCntnt( rPam, fnMoveForward ) )
+ {
+ rPos = aSavePos; // Cusror nicht veraendern
+ return FALSE;
+ }
+ (rNds.*fnMove->fnSection)( &rPos.nNode );
+ SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
+ rPos.nContent.Assign( pNd,
+ ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
+ return TRUE;
+}
+
+
+BOOL GoPrevSection( SwPaM & rPam, SwMoveFn fnMove )
+{
+ SwPosition& rPos = *rPam.GetPoint();
+ SwPosition aSavePos( rPos ); // eine Vergleichsposition
+ SwNodes& rNds = aSavePos.nNode.GetNodes();
+ rNds.GoStartOfSection( &rPos.nNode );
+
+ // kein weiterer ContentNode vorhanden ?
+ if( !GoInCntnt( rPam, fnMoveBackward ))
+ {
+ rPos = aSavePos; // Cusror nicht veraendern
+ return FALSE;
+ }
+ (rNds.*fnMove->fnSection)( &rPos.nNode );
+ SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
+ rPos.nContent.Assign( pNd,
+ ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ));
+ return TRUE;
+}
+
+// #111827#
+String SwPaM::GetTxt() const
+{
+ String aResult;
+
+ SwNodeIndex aNodeIndex = Start()->nNode;
+
+ /* The first node can be the end node. A first end node must be
+ handled, too. There fore do ... while and no incrementing of
+ aNodeIndex in the first pass.
+ */
+ bool bFirst = true;
+ do
+ {
+ if (! bFirst)
+ {
+ aNodeIndex++;
+ }
+
+ bFirst = false;
+
+ SwTxtNode * pTxtNode = aNodeIndex.GetNode().GetTxtNode();
+
+ if (pTxtNode != NULL)
+ {
+ const String & aTmpStr = pTxtNode->GetTxt();
+
+ if (aNodeIndex == Start()->nNode)
+ {
+ xub_StrLen nEnd;
+ if (End()->nNode == aNodeIndex)
+ nEnd = End()->nContent.GetIndex();
+ else
+ nEnd = aTmpStr.Len();
+
+ aResult += aTmpStr.Copy(Start()->nContent.GetIndex(),
+ nEnd - Start()->nContent.GetIndex()) ;
+ }
+ else if (aNodeIndex == End()->nNode)
+ aResult += aTmpStr.Copy(0, End()->nContent.GetIndex());
+ else
+ aResult += aTmpStr;
+ }
+ }
+ while (aNodeIndex != End()->nNode);
+
+ return aResult;
+}
+
+BOOL SwPaM::Overlap(const SwPaM & a, const SwPaM & b)
+{
+ return !(*b.End() <= *a.Start() || *a.End() <= *b.End());
+}
+
+void SwPaM::InvalidatePaM()
+{
+ const SwNode *_pNd=this->GetNode();
+ const SwTxtNode *_pTxtNd=(_pNd!=NULL?_pNd->GetTxtNode():NULL);
+ if (_pTxtNd!=NULL)
+ {
+ // pretent that the PaM marks inserted text to recalc the portion...
+ SwInsTxt aHint( Start()->nContent.GetIndex(),
+ End()->nContent.GetIndex() - Start()->nContent.GetIndex() + 1 );
+ SwModify *_pModify=(SwModify*)_pTxtNd;
+ _pModify->Modify( 0, &aHint);
+ }
+}
+
+BOOL SwPaM::LessThan(const SwPaM & a, const SwPaM & b)
+{
+ return (*a.Start() < *b.Start()) || (*a.Start() == *b.Start() && *a.End() < *b.End());
+}