/************************************************************** * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include // --> FME 2004-06-29 #114856# Formular view #include #include #include #include // <-- #include // #111827# #include #include // 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()); }