blob: 44e2e22b3ac197daefb7dd565116dafd6c25ad3e [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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( sal_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;
}
sal_Bool SwPosition::operator<(const SwPosition &rPos) const
{
if( nNode < rPos.nNode )
return sal_True;
if( nNode == rPos.nNode )
return ( nContent < rPos.nContent );
return sal_False;
}
sal_Bool SwPosition::operator>(const SwPosition &rPos) const
{
if(nNode > rPos.nNode )
return sal_True;
if( nNode == rPos.nNode )
return ( nContent > rPos.nContent );
return sal_False;
}
sal_Bool SwPosition::operator<=(const SwPosition &rPos) const
{
if(nNode < rPos.nNode )
return sal_True;
if( nNode == rPos.nNode )
return ( nContent <= rPos.nContent );
return sal_False;
}
sal_Bool SwPosition::operator>=(const SwPosition &rPos) const
{
if(nNode > rPos.nNode )
return sal_True;
if( nNode == rPos.nNode )
return ( nContent >= rPos.nContent );
return sal_False;
}
sal_Bool SwPosition::operator==(const SwPosition &rPos) const
{
return
( ( nNode == rPos.nNode ) && ( nContent == rPos.nContent ) ?
sal_True: sal_False);
}
sal_Bool SwPosition::operator!=(const SwPosition &rPos) const
{
if( nNode != rPos.nNode )
return sal_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( sal_uLong nSttIdx, sal_uLong nEndIdx, const SwNode& rEndNd )
{
sal_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;
}
sal_Bool lcl_ChkOneRange( CHKSECTION eSec, sal_Bool bChkSections,
const SwNode& rBaseEnd, sal_uLong nStt, sal_uLong nEnd )
{
if( eSec != Chk_Both )
return sal_False;
if( !bChkSections )
return sal_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 sal_True; // der gleiche StartNode, die selbe Section
// steht schon auf einem GrundSection Node ? Fehler !!!
if( !pNd->StartOfSectionIndex() )
return sal_False;
while( ( pTmp = pNd->StartOfSectionNode())->EndOfSectionNode() !=
&rBaseEnd )
pNd = pTmp;
sal_uLong nSttIdx = pNd->GetIndex(), nEndIdx = pNd->EndOfSectionIndex();
return nSttIdx <= nStt && nStt <= nEndIdx &&
nSttIdx <= nEnd && nEnd <= nEndIdx ? sal_True : sal_False;
}
sal_Bool CheckNodesRange( const SwNodeIndex& rStt,
const SwNodeIndex& rEnd, sal_Bool bChkSection )
{
const SwNodes& rNds = rStt.GetNodes();
sal_uLong nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
CHKSECTION eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfContent() );
if( Chk_None != eSec ) return eSec == Chk_Both ? sal_True : sal_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 sal_False; // liegt irgendwo dazwischen, FEHLER
}
sal_Bool GoNext(SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
{
if( pNd->IsCntntNode() )
return ((SwCntntNode*)pNd)->GoNext( pIdx, nMode );
return sal_False;
}
sal_Bool GoPrevious( SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
{
if( pNd->IsCntntNode() )
return ((SwCntntNode*)pNd)->GoPrevious( pIdx, nMode );
return sal_False;
}
SwCntntNode* GoNextNds( SwNodeIndex* pIdx, sal_Bool bChk )
{
SwNodeIndex aIdx( *pIdx );
SwCntntNode* pNd = aIdx.GetNodes().GoNext( &aIdx );
if( pNd )
{
if( bChk && 1 != aIdx.GetIndex() - pIdx->GetIndex() &&
!CheckNodesRange( *pIdx, aIdx, sal_True ) )
pNd = 0;
else
*pIdx = aIdx;
}
return pNd;
}
SwCntntNode* GoPreviousNds( SwNodeIndex * pIdx, sal_Bool bChk )
{
SwNodeIndex aIdx( *pIdx );
SwCntntNode* pNd = aIdx.GetNodes().GoPrevious( &aIdx );
if( pNd )
{
if( bChk && 1 != pIdx->GetIndex() - aIdx.GetIndex() &&
!CheckNodesRange( *pIdx, aIdx, sal_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
sal_Bool SwPaM::Move( SwMoveFn fnMove, SwGoInDoc fnGo )
{
sal_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(sal_Bool bPointFirst)
{
if (HasMark())
if ( ( bPointFirst && *m_pPoint > *m_pMark) ||
(!bPointFirst && *m_pPoint < *m_pMark) )
{
Exchange();
}
return *this;
}
sal_uInt16 SwPaM::GetPageNum( sal_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->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), pLayPos, pPos, sal_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.
sal_Bool SwPaM::HasReadonlySel( const bool bFormView ) const
{
sal_Bool bRet = sal_False;
const SwCntntNode* pNd = GetPoint()->nNode.GetNode().GetCntntNode();
const SwCntntFrm *pFrm = NULL;
if ( pNd != NULL )
{
Point aTmpPt;
pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), &aTmpPt, GetPoint(), sal_False );
}
// Will be set if point are inside edit-in-readonly environment
const SwFrm* pPointEditInReadonlyFrm = NULL;
if ( pFrm != NULL
&& ( pFrm->IsProtected()
|| ( bFormView
&& 0 == ( pPointEditInReadonlyFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
{
bRet = sal_True;
}
else if( pNd != NULL )
{
const SwSectionNode* pSNd = pNd->GetSectionNode();
if ( pSNd != NULL
&& ( pSNd->GetSection().IsProtectFlag()
|| ( bFormView
&& !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
{
bRet = sal_True;
}
}
if ( !bRet
&& HasMark()
&& GetPoint()->nNode != GetMark()->nNode )
{
pNd = GetMark()->nNode.GetNode().GetCntntNode();
pFrm = NULL;
if ( pNd != NULL )
{
Point aTmpPt;
pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), &aTmpPt, GetMark(), sal_False );
}
const SwFrm* pMarkEditInReadonlyFrm = NULL;
if ( pFrm != NULL
&& ( pFrm->IsProtected()
|| ( bFormView
&& 0 == ( pMarkEditInReadonlyFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
{
bRet = sal_True;
}
else if( pNd != NULL )
{
const SwSectionNode* pSNd = pNd->GetSectionNode();
if ( pSNd != NULL
&& ( pSNd->GetSection().IsProtectFlag()
|| ( bFormView
&& !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
{
bRet = sal_True;
}
}
if ( !bRet && bFormView )
{
// Check if start and end frame are inside the _same_
// edit-in-readonly-environment. Otherwise we better return 'true'
if ( pPointEditInReadonlyFrm != pMarkEditInReadonlyFrm )
bRet = sal_True;
}
// check for protected section inside the selection
if( !bRet )
{
sal_uLong nSttIdx = GetMark()->nNode.GetIndex(),
nEndIdx = GetPoint()->nNode.GetIndex();
if( nEndIdx <= nSttIdx )
{
sal_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( sal_uInt16 n = rFmts.Count(); n; )
{
const SwSectionFmt* pFmt = rFmts[ --n ];
if( pFmt->GetProtect().IsCntntProtected() )
{
const SwFmtCntnt& rCntnt = pFmt->GetCntnt(sal_False);
ASSERT( rCntnt.GetCntntIdx(), "wo ist der SectionNode?" );
sal_uLong nIdx = rCntnt.GetCntntIdx()->GetIndex();
if( nSttIdx <= nIdx && nEndIdx >= nIdx &&
rCntnt.GetCntntIdx()->GetNode().GetNodes().IsDocNodes() )
{
bRet = sal_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 );
sal_uLong nIdx = pTbl ? pTbl->GetTabSortBoxes()[0]->GetSttIdx()
: 0;
if( nSttIdx <= nIdx && nEndIdx >= nIdx )
{
// dann teste mal alle Boxen
const SwTableSortBoxes& rBoxes = pTbl->GetTabSortBoxes();
for( sal_uInt16 i = rBoxes.Count(); i; )
if( rBoxes[ --i ]->GetFrmFmt()->GetProtect().
IsCntntProtected() )
{
bRet = sal_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, sal_Bool& rbFirst, SwMoveFn fnMove,
sal_Bool bInReadOnly )
{
SwCntntNode * pNd = 0;
SwCntntFrm* pFrm;
if( ((*rPam.GetPoint()).*fnMove->fnCmpOp)( *rPam.GetMark() ) ||
( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) )
{
if( rbFirst )
{
rbFirst = sal_False;
pNd = rPam.GetCntntNode();
if( pNd )
{
if(
(
0 == ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout() ) ) ||
( !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() );
sal_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( sal_True )
{
pNd = bSrchForward
? rNodes.GoNextSection( &aPos.nNode, sal_True, !bInReadOnly )
: rNodes.GoPrevSection( &aPos.nNode, sal_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->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout() ) ) ||
( !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, sal_True );
if( pCNd )
pCNd->MakeEndIndex( &pPos->nContent );
}
void GoStartSection( SwPosition * pPos )
{
// springe zum Anfang der Section
SwNodes& rNodes = pPos->nNode.GetNodes();
sal_uInt16 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();
sal_uInt16 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, sal_True ) )
pPos->nNode.GetNode().GetCntntNode()->MakeEndIndex( &pPos->nContent );
}
sal_Bool GoInDoc( SwPaM & rPam, SwMoveFn fnMove )
{
(*fnMove->fnDoc)( rPam.GetPoint() );
return sal_True;
}
sal_Bool GoInSection( SwPaM & rPam, SwMoveFn fnMove )
{
(*fnMove->fnSections)( (SwPosition*)rPam.GetPoint() );
return sal_True;
}
sal_Bool GoInNode( SwPaM & rPam, SwMoveFn fnMove )
{
SwCntntNode *pNd = (*fnMove->fnNds)( &rPam.GetPoint()->nNode, sal_True );
if( pNd )
rPam.GetPoint()->nContent.Assign( pNd,
::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
return 0 != pNd;
}
sal_Bool GoInCntnt( SwPaM & rPam, SwMoveFn fnMove )
{
if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
&rPam.GetPoint()->nContent, CRSR_SKIP_CHARS ))
return sal_True;
return GoInNode( rPam, fnMove );
}
sal_Bool GoInCntntCells( SwPaM & rPam, SwMoveFn fnMove )
{
if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
&rPam.GetPoint()->nContent, CRSR_SKIP_CELLS ))
return sal_True;
return GoInNode( rPam, fnMove );
}
sal_Bool GoInCntntSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
{
if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
&rPam.GetPoint()->nContent, CRSR_SKIP_CHARS | CRSR_SKIP_HIDDEN ) )
return sal_True;
return GoInNode( rPam, fnMove );
}
sal_Bool GoInCntntCellsSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
{
if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
&rPam.GetPoint()->nContent, CRSR_SKIP_CELLS | CRSR_SKIP_HIDDEN ) )
return sal_True;
return GoInNode( rPam, fnMove );
}
// --------- Funktionsdefinitionen fuer die SwCrsrShell --------------
sal_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 sal_True;
}
return sal_False;
}
sal_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 sal_True;
}
}
// den Node noch etwas bewegen ( auf den naechsten/vorh. CntntNode)
if( ( aPosPara==fnParaStart && 0 != ( pNd =
GoPreviousNds( &rPos.nNode, sal_True ))) ||
( aPosPara==fnParaEnd && 0 != ( pNd =
GoNextNds( &rPos.nNode, sal_True ))) )
{
rPos.nContent.Assign( pNd,
::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ));
return sal_True;
}
return sal_False;
}
sal_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 sal_True;
}
return sal_False;
}
sal_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, sal_True )) )
{
rPos = aSavePos; // Cusror nicht veraendern
return sal_False;
}
rPos.nContent.Assign( pNd,
::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
return aSavePos != rPos;
}
sal_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 sal_False;
}
(rNds.*fnMove->fnSection)( &rPos.nNode );
SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
rPos.nContent.Assign( pNd,
::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
return sal_True;
}
sal_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 sal_False;
}
(rNds.*fnMove->fnSection)( &rPos.nNode );
SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
rPos.nContent.Assign( pNd,
::GetSttOrEnd( fnMove == fnMoveForward, *pNd ));
return sal_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;
}
sal_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->ModifyNotification( 0, &aHint);
}
}
sal_Bool SwPaM::LessThan(const SwPaM & a, const SwPaM & b)
{
return (*a.Start() < *b.Start()) || (*a.Start() == *b.Start() && *a.End() < *b.End());
}