diff options
Diffstat (limited to 'sw/source/core/docnode/node.cxx')
-rw-r--r-- | sw/source/core/docnode/node.cxx | 2028 |
1 files changed, 2028 insertions, 0 deletions
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx new file mode 100644 index 000000000000..26521624abb7 --- /dev/null +++ b/sw/source/core/docnode/node.cxx @@ -0,0 +1,2028 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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/frmdiritem.hxx> +#include <editeng/protitem.hxx> +#include <com/sun/star/i18n/CharacterIteratorMode.hdl> +#include <fmtcntnt.hxx> +#include <fmtanchr.hxx> +#include <frmfmt.hxx> +#include <txtftn.hxx> +#include <ftnfrm.hxx> +#include <doc.hxx> +#include <docary.hxx> +#include <node.hxx> +#include <ndindex.hxx> +#include <numrule.hxx> +#include <swtable.hxx> +#include <ndtxt.hxx> +#include <pam.hxx> +#include <swcache.hxx> +#include <section.hxx> +#include <cntfrm.hxx> +#include <flyfrm.hxx> +#include <txtfrm.hxx> +#include <tabfrm.hxx> // SwTabFrm +#include <viewsh.hxx> +#include <paratr.hxx> +#include <ftnidx.hxx> +#include <fmtftn.hxx> +#include <fmthdft.hxx> +#include <frmatr.hxx> +#include <fmtautofmt.hxx> +#include <frmtool.hxx> +#include <pagefrm.hxx> +#include <node2lay.hxx> +#include <pagedesc.hxx> +#include <fmtpdsc.hxx> +#include <breakit.hxx> +#include <crsskip.hxx> +#include <SwStyleNameMapper.hxx> +#include <scriptinfo.hxx> +#include <rootfrm.hxx> +#include <istyleaccess.hxx> +#include <IDocumentListItems.hxx> +#include <switerator.hxx> +#include "ndole.hxx" + +using namespace ::com::sun::star::i18n; + +TYPEINIT2( SwCntntNode, SwModify, SwIndexReg ) + +/* + * Some local helper functions for the attribute set handle of a content node. + * Since the attribute set of a content node may not be modified directly, + * we always have to create a new SwAttrSet, do the modifications, and get + * a new handle from the style access + */ + +namespace AttrSetHandleHelper +{ + +void GetNewAutoStyle( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, + const SwCntntNode& rNode, + SwAttrSet& rNewAttrSet ) +{ + const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get()); + if( rNode.GetModifyAtAttr() ) + const_cast<SwAttrSet*>(pAttrSet)->SetModifyAtAttr( 0 ); + IStyleAccess& rSA = pAttrSet->GetPool()->GetDoc()->GetIStyleAccess(); + mrpAttrSet = rSA.getAutomaticStyle( rNewAttrSet, rNode.IsTxtNode() ? + IStyleAccess::AUTO_STYLE_PARA : + IStyleAccess::AUTO_STYLE_NOTXT ); + const bool bSetModifyAtAttr = ((SwAttrSet*)mrpAttrSet.get())->SetModifyAtAttr( &rNode ); + rNode.SetModifyAtAttr( bSetModifyAtAttr ); +} + + +void SetParent( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, + const SwCntntNode& rNode, + const SwFmt* pParentFmt, + const SwFmt* pConditionalFmt ) +{ + const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get()); + OSL_ENSURE( pAttrSet, "no SwAttrSet" ); + OSL_ENSURE( pParentFmt || !pConditionalFmt, "ConditionalFmt without ParentFmt?" ); + + const SwAttrSet* pParentSet = pParentFmt ? &pParentFmt->GetAttrSet() : 0; + + if ( pParentSet != pAttrSet->GetParent() ) + { + SwAttrSet aNewSet( *pAttrSet ); + aNewSet.SetParent( pParentSet ); + aNewSet.ClearItem( RES_FRMATR_STYLE_NAME ); + aNewSet.ClearItem( RES_FRMATR_CONDITIONAL_STYLE_NAME ); + String sVal; + + if ( pParentFmt ) + { + SwStyleNameMapper::FillProgName( pParentFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True ); + const SfxStringItem aAnyFmtColl( RES_FRMATR_STYLE_NAME, sVal ); + aNewSet.Put( aAnyFmtColl ); + + if ( pConditionalFmt != pParentFmt ) + SwStyleNameMapper::FillProgName( pConditionalFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True ); + + const SfxStringItem aFmtColl( RES_FRMATR_CONDITIONAL_STYLE_NAME, sVal ); + aNewSet.Put( aFmtColl ); + } + + GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); + } +} + +const SfxPoolItem* Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, + const SwCntntNode& rNode, + const SfxPoolItem& rAttr ) +{ + SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); + const SfxPoolItem* pRet = aNewSet.Put( rAttr ); + if ( pRet ) + GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); + return pRet; +} + +int Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, const SwCntntNode& rNode, + const SfxItemSet& rSet ) +{ + SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); + + // --> FME 2007-4-12 #i76273# Robust: Save the style name items: + SfxItemSet* pStyleNames = 0; + if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, sal_False ) ) + { + pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME ); + pStyleNames->Put( aNewSet ); + } + // <-- + + const int nRet = aNewSet.Put( rSet ); + + // --> FME 2007-4-12 #i76273# Robust: Save the style name items: + if ( pStyleNames ) + { + aNewSet.Put( *pStyleNames ); + delete pStyleNames; + } + // <-- + + if ( nRet ) + GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); + + return nRet; +} + +int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, + const SwCntntNode& rNode, const SfxPoolItem& rAttr, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); + + // for a correct broadcast, we need to do a SetModifyAtAttr with the items + // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle + if( rNode.GetModifyAtAttr() ) + aNewSet.SetModifyAtAttr( &rNode ); + + const int nRet = aNewSet.Put_BC( rAttr, pOld, pNew ); + + if ( nRet ) + GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); + + return nRet; +} + +int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, + const SwCntntNode& rNode, const SfxItemSet& rSet, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); + + // --> FME 2007-4-12 #i76273# Robust: Save the style name items: + SfxItemSet* pStyleNames = 0; + if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, sal_False ) ) + { + pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME ); + pStyleNames->Put( aNewSet ); + } + // <-- + + // for a correct broadcast, we need to do a SetModifyAtAttr with the items + // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle + if( rNode.GetModifyAtAttr() ) + aNewSet.SetModifyAtAttr( &rNode ); + + const int nRet = aNewSet.Put_BC( rSet, pOld, pNew ); + + // --> FME 2007-4-12 #i76273# Robust: Save the style name items: + if ( pStyleNames ) + { + aNewSet.Put( *pStyleNames ); + delete pStyleNames; + } + // <-- + + if ( nRet ) + GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); + + return nRet; +} + +sal_uInt16 ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, + const SwCntntNode& rNode, sal_uInt16 nWhich, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); + if( rNode.GetModifyAtAttr() ) + aNewSet.SetModifyAtAttr( &rNode ); + const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich, pOld, pNew ); + if ( nRet ) + GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); + return nRet; +} + +sal_uInt16 ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, + const SwCntntNode& rNode, + sal_uInt16 nWhich1, sal_uInt16 nWhich2, + SwAttrSet* pOld, SwAttrSet* pNew ) +{ + SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); + if( rNode.GetModifyAtAttr() ) + aNewSet.SetModifyAtAttr( &rNode ); + const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich1, nWhich2, pOld, pNew ); + if ( nRet ) + GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); + return nRet; +} + +} + +/******************************************************************* +|* +|* SwNode::GetSectionLevel +|* +|* Beschreibung +|* Die Funktion liefert den Sectionlevel an der durch +|* aIndex bezeichneten Position. +|* +|* Die Logik ist wie folgt: ( S -> Start, E -> End, C -> CntntNode) +|* Level 0 E +|* 1 S E +|* 2 SC +|* +|* alle EndNodes der GrundSection haben den Level 0 +|* alle StartNodes der GrundSection haben den Level 1 +|* +*******************************************************************/ + + +sal_uInt16 SwNode::GetSectionLevel() const +{ + // EndNode einer Grund-Section ?? diese sind immer 0 !! + if( IsEndNode() && 0 == pStartOfSection->StartOfSectionIndex() ) + return 0; + + sal_uInt16 nLevel; + const SwNode* pNode = IsStartNode() ? this : pStartOfSection; + for( nLevel = 1; 0 != pNode->StartOfSectionIndex(); ++nLevel ) + pNode = pNode->pStartOfSection; + return IsEndNode() ? nLevel-1 : nLevel; +} + +/******************************************************************* +|* +|* SwNode::SwNode +|* +|* Beschreibung +|* Konstruktor; dieser fuegt einen Node in das Array rNodes +|* an der Position rWhere ein. Dieser bekommt als +|* theEndOfSection den EndOfSection-Index des Nodes +|* unmittelbar vor ihm. Falls er sich an der Position 0 +|* innerhalb des variablen Arrays befindet, wird +|* theEndOfSection 0 (der neue selbst). +|* +|* Parameter +|* IN +|* rNodes bezeichnet das variable Array, in das der Node +|* eingefuegt werden soll +|* IN +|* rWhere bezeichnet die Position innerhalb dieses Arrays, +|* an der der Node eingefuegt werden soll +|* +*******************************************************************/ + +#if OSL_DEBUG_LEVEL > 1 +long SwNode::nSerial = 0; +#endif + +SwNode::SwNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType ) + : nNodeType( nNdType ), pStartOfSection( 0 ) +{ + bSetNumLSpace = bIgnoreDontExpand = sal_False; + nAFmtNumLvl = 0; + + SwNodes& rNodes = (SwNodes&)rWhere.GetNodes(); + SwNode* pInsNd = this; // der MAC kann this nicht einfuegen !! + if( rWhere.GetIndex() ) + { + SwNode* pNd = rNodes[ rWhere.GetIndex() -1 ]; + rNodes.InsertNode( pInsNd, rWhere ); + if( 0 == ( pStartOfSection = pNd->GetStartNode()) ) + { + pStartOfSection = pNd->pStartOfSection; + if( pNd->GetEndNode() ) // EndNode ? Section ueberspringen! + { + pNd = pStartOfSection; + pStartOfSection = pNd->pStartOfSection; + } + } + } + else + { + rNodes.InsertNode( pInsNd, rWhere ); + pStartOfSection = (SwStartNode*)this; + } + +#if OSL_DEBUG_LEVEL > 1 + nMySerial = nSerial; + nSerial++; +#endif +} + +SwNode::SwNode( SwNodes& rNodes, sal_uLong nPos, const sal_uInt8 nNdType ) + : nNodeType( nNdType ), pStartOfSection( 0 ) +{ + bSetNumLSpace = bIgnoreDontExpand = sal_False; + nAFmtNumLvl = 0; + + SwNode* pInsNd = this; // der MAC kann this nicht einfuegen !! + if( nPos ) + { + SwNode* pNd = rNodes[ nPos - 1 ]; + rNodes.InsertNode( pInsNd, nPos ); + if( 0 == ( pStartOfSection = pNd->GetStartNode()) ) + { + pStartOfSection = pNd->pStartOfSection; + if( pNd->GetEndNode() ) // EndNode ? Section ueberspringen! + { + pNd = pStartOfSection; + pStartOfSection = pNd->pStartOfSection; + } + } + } + else + { + rNodes.InsertNode( pInsNd, nPos ); + pStartOfSection = (SwStartNode*)this; + } + +#if OSL_DEBUG_LEVEL > 1 + nMySerial = nSerial; + nSerial++; +#endif +} + +SwNode::~SwNode() +{ +} + +// suche den TabellenNode, in dem dieser steht. Wenn in keiner +// Tabelle wird 0 returnt. + + +SwTableNode* SwNode::FindTableNode() +{ + if( IsTableNode() ) + return GetTableNode(); + SwStartNode* pTmp = pStartOfSection; + while( !pTmp->IsTableNode() && pTmp->GetIndex() ) +#if defined( ALPHA ) && defined( UNX ) + pTmp = ((SwNode*)pTmp)->pStartOfSection; +#else + pTmp = pTmp->pStartOfSection; +#endif + return pTmp->GetTableNode(); +} + + +// liegt der Node im Sichtbarenbereich der Shell ? +sal_Bool SwNode::IsInVisibleArea( ViewShell* pSh ) const +{ + sal_Bool bRet = sal_False; + const SwCntntNode* pNd; + + if( ND_STARTNODE & nNodeType ) + { + SwNodeIndex aIdx( *this ); + pNd = GetNodes().GoNext( &aIdx ); + } + else if( ND_ENDNODE & nNodeType ) + { + SwNodeIndex aIdx( *EndOfSectionNode() ); + pNd = GetNodes().GoPrevious( &aIdx ); + } + else + pNd = GetCntntNode(); + + if( !pSh ) + // dann die Shell vom Doc besorgen: + GetDoc()->GetEditShell( &pSh ); + + if( pSh ) + { + const SwFrm* pFrm; + if( pNd && 0 != ( pFrm = pNd->getLayoutFrm( pSh->GetLayout(), 0, 0, sal_False ) ) ) + { + + if ( pFrm->IsInTab() ) + pFrm = pFrm->FindTabFrm(); + + if( !pFrm->IsValid() ) + do + { pFrm = pFrm->FindPrev(); + } while ( pFrm && !pFrm->IsValid() ); + + if( !pFrm || pSh->VisArea().IsOver( pFrm->Frm() ) ) + bRet = sal_True; + } + } + + return bRet; +} + +sal_Bool SwNode::IsInProtectSect() const +{ + const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this; + const SwSectionNode* pSectNd = pNd->FindSectionNode(); + return pSectNd && pSectNd->GetSection().IsProtectFlag(); +} + + // befindet sich der Node in irgendetwas geschuetzten ? + // (Bereich/Rahmen/Tabellenzellen/... incl. des Ankers bei + // Rahmen/Fussnoten/..) +sal_Bool SwNode::IsProtect() const +{ + const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this; + const SwStartNode* pSttNd = pNd->FindSectionNode(); + if( pSttNd && ((SwSectionNode*)pSttNd)->GetSection().IsProtectFlag() ) + return sal_True; + + if( 0 != ( pSttNd = FindTableBoxStartNode() ) ) + { + SwCntntFrm* pCFrm; + if( IsCntntNode() && 0 != (pCFrm = ((SwCntntNode*)this)->getLayoutFrm( GetDoc()->GetCurrentLayout() ) )) + return pCFrm->IsProtected(); + + const SwTableBox* pBox = pSttNd->FindTableNode()->GetTable(). + GetTblBox( pSttNd->GetIndex() ); + //Robust #149568 + if( pBox && pBox->GetFrmFmt()->GetProtect().IsCntntProtected() ) + return sal_True; + } + + SwFrmFmt* pFlyFmt = GetFlyFmt(); + if( pFlyFmt ) + { + if( pFlyFmt->GetProtect().IsCntntProtected() ) + return sal_True; + const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor(); + return rAnchor.GetCntntAnchor() + ? rAnchor.GetCntntAnchor()->nNode.GetNode().IsProtect() + : sal_False; + } + + if( 0 != ( pSttNd = FindFootnoteStartNode() ) ) + { + const SwTxtFtn* pTFtn = GetDoc()->GetFtnIdxs().SeekEntry( + SwNodeIndex( *pSttNd ) ); + if( pTFtn ) + return pTFtn->GetTxtNode().IsProtect(); + } + + return sal_False; +} + + // suche den PageDesc, mit dem dieser Node formatiert ist. Wenn das + // Layout vorhanden ist wird ueber das gesucht, ansonsten gibt es nur + // die harte Tour ueber die Nodes nach vorne suchen!! +const SwPageDesc* SwNode::FindPageDesc( sal_Bool bCalcLay, + sal_uInt32* pPgDescNdIdx ) const +{ + if ( !GetNodes().IsDocNodes() ) + { + return 0; + } + + const SwPageDesc* pPgDesc = 0; + + const SwCntntNode* pNode; + if( ND_STARTNODE & nNodeType ) + { + SwNodeIndex aIdx( *this ); + pNode = GetNodes().GoNext( &aIdx ); + } + else if( ND_ENDNODE & nNodeType ) + { + SwNodeIndex aIdx( *EndOfSectionNode() ); + pNode = GetNodes().GoPrevious( &aIdx ); + } + else + { + pNode = GetCntntNode(); + if( pNode ) + pPgDesc = ((SwFmtPageDesc&)pNode->GetAttr( RES_PAGEDESC )).GetPageDesc(); + } + + // geht es uebers Layout? + if( !pPgDesc ) + { + const SwFrm* pFrm; + const SwPageFrm* pPage; + if( pNode && 0 != ( pFrm = pNode->getLayoutFrm( pNode->GetDoc()->GetCurrentLayout(), 0, 0, bCalcLay ) ) && + 0 != ( pPage = pFrm->FindPageFrm() ) ) + { + pPgDesc = pPage->GetPageDesc(); + if ( pPgDescNdIdx ) + { + *pPgDescNdIdx = pNode->GetIndex(); + } + } + } + + if( !pPgDesc ) + { + // dann also uebers Nodes-Array + const SwDoc* pDoc = GetDoc(); + const SwNode* pNd = this; + const SwStartNode* pSttNd; + if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() && + 0 != ( pSttNd = pNd->FindFlyStartNode() ) ) + { + // dann erstmal den richtigen Anker finden + const SwFrmFmt* pFmt = 0; + const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts(); + sal_uInt16 n; + + for( n = 0; n < rFmts.Count(); ++n ) + { + SwFrmFmt* pFrmFmt = rFmts[ n ]; + const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); + if( rCntnt.GetCntntIdx() && + &rCntnt.GetCntntIdx()->GetNode() == (SwNode*)pSttNd ) + { + pFmt = pFrmFmt; + break; + } + } + + if( pFmt ) + { + const SwFmtAnchor* pAnchor = &pFmt->GetAnchor(); + if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) && + pAnchor->GetCntntAnchor() ) + { + pNd = &pAnchor->GetCntntAnchor()->nNode.GetNode(); + const SwNode* pFlyNd = pNd->FindFlyStartNode(); + while( pFlyNd ) + { + // dann ueber den Anker nach oben "hangeln" + for( n = 0; n < rFmts.Count(); ++n ) + { + const SwFrmFmt* pFrmFmt = rFmts[ n ]; + const SwNodeIndex* pIdx = pFrmFmt->GetCntnt(). + GetCntntIdx(); + if( pIdx && pFlyNd == &pIdx->GetNode() ) + { + if( pFmt == pFrmFmt ) + { + pNd = pFlyNd; + pFlyNd = 0; + break; + } + pAnchor = &pFrmFmt->GetAnchor(); + if ((FLY_AT_PAGE == pAnchor->GetAnchorId()) || + !pAnchor->GetCntntAnchor() ) + { + pFlyNd = 0; + break; + } + + pFlyNd = pAnchor->GetCntntAnchor()->nNode. + GetNode().FindFlyStartNode(); + break; + } + } + if( n >= rFmts.Count() ) + { + OSL_ENSURE( !this, "Fly-Section aber kein Format gefunden" ); + return sal_False; + } + } + } + } + // in pNd sollte jetzt der richtige Anker Node stehen oder + // immer noch der this + } + + if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) + { + if( pNd->GetIndex() > GetNodes().GetEndOfAutotext().GetIndex() ) + { + pPgDesc = &pDoc->GetPageDesc( 0 ); + pNd = 0; + } + else + { + // suche den Body Textnode + if( 0 != ( pSttNd = pNd->FindHeaderStartNode() ) || + 0 != ( pSttNd = pNd->FindFooterStartNode() )) + { + // dann in den PageDescs diesen StartNode suchen + sal_uInt16 nId; + UseOnPage eAskUse; + if( SwHeaderStartNode == pSttNd->GetStartNodeType()) + { + nId = RES_HEADER; + eAskUse = nsUseOnPage::PD_HEADERSHARE; + } + else + { + nId = RES_FOOTER; + eAskUse = nsUseOnPage::PD_FOOTERSHARE; + } + + for( sal_uInt16 n = pDoc->GetPageDescCnt(); n && !pPgDesc; ) + { + const SwPageDesc& rPgDsc = pDoc->GetPageDesc( --n ); + const SwFrmFmt* pFmt = &rPgDsc.GetMaster(); + int nStt = 0, nLast = 1; + if( !( eAskUse & rPgDsc.ReadUseOn() )) ++nLast; + + for( ; nStt < nLast; ++nStt, pFmt = &rPgDsc.GetLeft() ) + { + const SwFmtHeader& rHdFt = (SwFmtHeader&) + pFmt->GetFmtAttr( nId ); + if( rHdFt.GetHeaderFmt() ) + { + const SwFmtCntnt& rCntnt = + rHdFt.GetHeaderFmt()->GetCntnt(); + if( rCntnt.GetCntntIdx() && + &rCntnt.GetCntntIdx()->GetNode() == + (SwNode*)pSttNd ) + { + pPgDesc = &rPgDsc; + break; + } + } + } + } + + if( !pPgDesc ) + pPgDesc = &pDoc->GetPageDesc( 0 ); + pNd = 0; + } + else if( 0 != ( pSttNd = pNd->FindFootnoteStartNode() )) + { + // der Anker kann nur im Bodytext sein + const SwTxtFtn* pTxtFtn; + const SwFtnIdxs& rFtnArr = pDoc->GetFtnIdxs(); + for( sal_uInt16 n = 0; n < rFtnArr.Count(); ++n ) + if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() && + (SwNode*)pSttNd == + &pTxtFtn->GetStartNode()->GetNode() ) + { + pNd = &pTxtFtn->GetTxtNode(); + break; + } + } + else + { + // kann jetzt nur noch ein Seitengebundener Fly sein + // oder irgendetwas neueres. + // Hier koennen wir nur noch den Standard returnen + OSL_ENSURE( pNd->FindFlyStartNode(), + "wo befindet sich dieser Node?" ); + + pPgDesc = &pDoc->GetPageDesc( 0 ); + pNd = 0; + } + } + } + + if( pNd ) + { + SwFindNearestNode aInfo( *pNd ); + // dann ueber alle Nodes aller PageDesc + const SfxPoolItem* pItem; + sal_uInt32 i, nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_PAGEDESC ); + for( i = 0; i < nMaxItems; ++i ) + if( 0 != (pItem = pDoc->GetAttrPool().GetItem2( RES_PAGEDESC, i ) ) && + ((SwFmtPageDesc*)pItem)->GetDefinedIn() ) + { + const SwModify* pMod = ((SwFmtPageDesc*)pItem)->GetDefinedIn(); + if( pMod->ISA( SwCntntNode ) ) + aInfo.CheckNode( *(SwCntntNode*)pMod ); + else if( pMod->ISA( SwFmt )) + ((SwFmt*)pMod)->GetInfo( aInfo ); + } + + if( 0 != ( pNd = aInfo.GetFoundNode() )) + { + if( pNd->IsCntntNode() ) + pPgDesc = ((SwFmtPageDesc&)pNd->GetCntntNode()-> + GetAttr( RES_PAGEDESC )).GetPageDesc(); + else if( pNd->IsTableNode() ) + pPgDesc = pNd->GetTableNode()->GetTable(). + GetFrmFmt()->GetPageDesc().GetPageDesc(); + else if( pNd->IsSectionNode() ) + pPgDesc = pNd->GetSectionNode()->GetSection(). + GetFmt()->GetPageDesc().GetPageDesc(); + if ( pPgDescNdIdx ) + { + *pPgDescNdIdx = pNd->GetIndex(); + } + } + if( !pPgDesc ) + pPgDesc = &pDoc->GetPageDesc( 0 ); + } + } + return pPgDesc; +} + + + // falls der Node in einem Fly steht, dann wird das entsprechende Format + // returnt +SwFrmFmt* SwNode::GetFlyFmt() const +{ + SwFrmFmt* pRet = 0; + const SwNode* pSttNd = FindFlyStartNode(); + if( pSttNd ) + { + if( IsCntntNode() ) + { + SwCntntFrm* pFrm = SwIterator<SwCntntFrm,SwCntntNode>::FirstElement( *(SwCntntNode*)this ); + if( pFrm ) + pRet = pFrm->FindFlyFrm()->GetFmt(); + } + if( !pRet ) + { + // dann gibts noch harten steinigen Weg uebers Dokument: + const SwSpzFrmFmts& rFrmFmtTbl = *GetDoc()->GetSpzFrmFmts(); + for( sal_uInt16 n = 0; n < rFrmFmtTbl.Count(); ++n ) + { + SwFrmFmt* pFmt = rFrmFmtTbl[n]; + const SwFmtCntnt& rCntnt = pFmt->GetCntnt(); + if( rCntnt.GetCntntIdx() && + &rCntnt.GetCntntIdx()->GetNode() == pSttNd ) + { + pRet = pFmt; + break; + } + } + } + } + return pRet; +} + +SwTableBox* SwNode::GetTblBox() const +{ + SwTableBox* pBox = 0; + const SwNode* pSttNd = FindTableBoxStartNode(); + if( pSttNd ) + pBox = (SwTableBox*)pSttNd->FindTableNode()->GetTable().GetTblBox( + pSttNd->GetIndex() ); + return pBox; +} + +SwStartNode* SwNode::FindSttNodeByType( SwStartNodeType eTyp ) +{ + SwStartNode* pTmp = IsStartNode() ? (SwStartNode*)this : pStartOfSection; + + while( eTyp != pTmp->GetStartNodeType() && pTmp->GetIndex() ) +#if defined( ALPHA ) && defined( UNX ) + pTmp = ((SwNode*)pTmp)->pStartOfSection; +#else + pTmp = pTmp->pStartOfSection; +#endif + return eTyp == pTmp->GetStartNodeType() ? pTmp : 0; +} + +const SwTxtNode* SwNode::FindOutlineNodeOfLevel( sal_uInt8 nLvl ) const +{ + const SwTxtNode* pRet = 0; + const SwOutlineNodes& rONds = GetNodes().GetOutLineNds(); + if( MAXLEVEL > nLvl && rONds.Count() ) + { + sal_uInt16 nPos; + SwNode* pNd = (SwNode*)this; + sal_Bool bCheckFirst = sal_False; + if( !rONds.Seek_Entry( pNd, &nPos )) + { + if( nPos ) + nPos = nPos-1; + else + bCheckFirst = sal_True; + } + + if( bCheckFirst ) + { + // der 1.GliederungsNode liegt hinter dem Fragenden. Dann + // teste mal, ob dieser auf der gleichen Seite steht. Wenn + // nicht, ist das ein ungueltiger. Bug 61865 + pRet = rONds[0]->GetTxtNode(); + + const SwCntntNode* pCNd = GetCntntNode(); + + Point aPt( 0, 0 ); + const SwFrm* pFrm = pRet->getLayoutFrm( pRet->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False ), + * pMyFrm = pCNd ? pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False ) : 0; + const SwPageFrm* pPgFrm = pFrm ? pFrm->FindPageFrm() : 0; + if( pPgFrm && pMyFrm && + pPgFrm->Frm().Top() > pMyFrm->Frm().Top() ) + { + // der Fragende liegt vor der Seite, also ist er ungueltig + pRet = 0; + } + } + else + { + // oder ans Feld und von dort holen !! + while( nPos && + nLvl < ( pRet = rONds[nPos]->GetTxtNode() ) + ->GetAttrOutlineLevel() - 1 ) //<-end,zhaojianwei + --nPos; + + if( !nPos ) // bei 0 gesondert holen !! + pRet = rONds[0]->GetTxtNode(); + } + } + return pRet; +} + +inline sal_Bool IsValidNextPrevNd( const SwNode& rNd ) +{ + return ND_TABLENODE == rNd.GetNodeType() || + ( ND_CONTENTNODE & rNd.GetNodeType() ) || + ( ND_ENDNODE == rNd.GetNodeType() && rNd.StartOfSectionNode() && + ND_TABLENODE == rNd.StartOfSectionNode()->GetNodeType() ); +} + +sal_uInt8 SwNode::HasPrevNextLayNode() const +{ + // assumption: <this> node is a node inside the document nodes array section. + + sal_uInt8 nRet = 0; + if( IsValidNextPrevNd( *this )) + { + SwNodeIndex aIdx( *this, -1 ); + // #i77805# - skip section start and end nodes + while ( aIdx.GetNode().IsSectionNode() || + ( aIdx.GetNode().IsEndNode() && + aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) ) + { + --aIdx; + } + // <-- + if( IsValidNextPrevNd( aIdx.GetNode() )) + nRet |= ND_HAS_PREV_LAYNODE; + // #i77805# - skip section start and end nodes + aIdx = SwNodeIndex( *this, +1 ); + while ( aIdx.GetNode().IsSectionNode() || + ( aIdx.GetNode().IsEndNode() && + aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) ) + { + ++aIdx; + } + if( IsValidNextPrevNd( aIdx.GetNode() )) + nRet |= ND_HAS_NEXT_LAYNODE; + } + return nRet; +} + +/******************************************************************* +|* +|* SwNode::StartOfSection +|* +|* Beschreibung +|* Die Funktion liefert die StartOfSection des Nodes. +|* +|* Parameter +|* IN +|* rNodes bezeichnet das variable Array, in dem sich der Node +|* befindet +|* +*******************************************************************/ + + +SwStartNode::SwStartNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType, + SwStartNodeType eSttNd ) + : SwNode( rWhere, nNdType ), eSttNdTyp( eSttNd ) +{ + // erstmal temporaer, bis der EndNode eingefuegt wird. + pEndOfSection = (SwEndNode*)this; +} + +SwStartNode::SwStartNode( SwNodes& rNodes, sal_uLong nPos ) + : SwNode( rNodes, nPos, ND_STARTNODE ), eSttNdTyp( SwNormalStartNode ) +{ + // erstmal temporaer, bis der EndNode eingefuegt wird. + pEndOfSection = (SwEndNode*)this; +} + + +void SwStartNode::CheckSectionCondColl() const +{ +//FEATURE::CONDCOLL + SwNodeIndex aIdx( *this ); + sal_uLong nEndIdx = EndOfSectionIndex(); + const SwNodes& rNds = GetNodes(); + SwCntntNode* pCNd; + while( 0 != ( pCNd = rNds.GoNext( &aIdx )) && pCNd->GetIndex() < nEndIdx ) + pCNd->ChkCondColl(); +//FEATURE::CONDCOLL +} + +/******************************************************************* +|* +|* SwEndNode::SwEndNode +|* +|* Beschreibung +|* Konstruktor; dieser fuegt einen Node in das Array rNodes +|* an der Position aWhere ein. Der +|* theStartOfSection-Pointer wird entsprechend gesetzt, +|* und der EndOfSection-Pointer des zugehoerigen +|* Startnodes -- durch rStartOfSection bezeichnet -- +|* wird auf diesen Node gesetzt. +|* +|* Parameter +|* IN +|* rNodes bezeichnet das variable Array, in das der Node +|* eingefuegt werden soll +|* IN +|* aWhere bezeichnet die Position innerhalb dieses Arrays, +|* an der der Node eingefuegt werden soll +|* !!!!!!!!!!!! +|* Es wird eine Kopie uebergeben! +|* +*******************************************************************/ + + +SwEndNode::SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd ) + : SwNode( rWhere, ND_ENDNODE ) +{ + pStartOfSection = &rSttNd; + pStartOfSection->pEndOfSection = this; +} + +SwEndNode::SwEndNode( SwNodes& rNds, sal_uLong nPos, SwStartNode& rSttNd ) + : SwNode( rNds, nPos, ND_ENDNODE ) +{ + pStartOfSection = &rSttNd; + pStartOfSection->pEndOfSection = this; +} + + + +// -------------------- +// SwCntntNode +// -------------------- + + +SwCntntNode::SwCntntNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType, + SwFmtColl *pColl ) + : SwModify( pColl ), // CrsrsShell, FrameFmt, + SwNode( rWhere, nNdType ), + pCondColl( 0 ), + mbSetModifyAtAttr( false ) +{ +} + + +SwCntntNode::~SwCntntNode() +{ + // Die Basisklasse SwClient vom SwFrm nimmt sich aus + // der Abhaengikeitsliste raus! + // Daher muessen alle Frames in der Abhaengigkeitsliste geloescht werden. + if( GetDepends() ) + DelFrms(); + + if( pCondColl ) + delete pCondColl; + + if ( mpAttrSet.get() && mbSetModifyAtAttr ) + ((SwAttrSet*)mpAttrSet.get())->SetModifyAtAttr( 0 ); +} + +void SwCntntNode::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue ) +{ + sal_uInt16 nWhich = pOldValue ? pOldValue->Which() : + pNewValue ? pNewValue->Which() : 0 ; + + switch( nWhich ) + { + case RES_OBJECTDYING : + { + SwFmt * pFmt = (SwFmt *) ((SwPtrMsgPoolItem *)pNewValue)->pObject; + + // nicht umhaengen wenn dieses das oberste Format ist !! + if( GetRegisteredIn() == pFmt ) + { + if( pFmt->GetRegisteredIn() ) + { + // wenn Parent, dann im neuen Parent wieder anmelden + ((SwModify*)pFmt->GetRegisteredIn())->Add( this ); + if ( GetpSwAttrSet() ) + AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() ); + } + else + { + // sonst auf jeden Fall beim sterbenden abmelden + ((SwModify*)GetRegisteredIn())->Remove( this ); + if ( GetpSwAttrSet() ) + AttrSetHandleHelper::SetParent( mpAttrSet, *this, 0, 0 ); + } + } + } + break; + + + case RES_FMT_CHG: + // falls mein Format Parent umgesetzt wird, dann melde ich + // meinen Attrset beim Neuen an. + + // sein eigenes Modify ueberspringen !! + if( GetpSwAttrSet() && + ((SwFmtChg*)pNewValue)->pChangedFmt == GetRegisteredIn() ) + { + // den Set an den neuen Parent haengen + AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() ); + } + break; +//FEATURE::CONDCOLL + case RES_CONDCOLL_CONDCHG: + if( ((SwCondCollCondChg*)pNewValue)->pChangedFmt == GetRegisteredIn() && + &GetNodes() == &GetDoc()->GetNodes() ) + { + ChkCondColl(); + } + return ; // nicht an die Basisklasse / Frames weitergeben +//FEATURE::CONDCOLL + + case RES_ATTRSET_CHG: + if( GetNodes().IsDocNodes() && IsTxtNode() ) + { + if( SFX_ITEM_SET == ((SwAttrSetChg*)pOldValue)->GetChgSet()->GetItemState( + RES_CHRATR_HIDDEN, sal_False ) ) + { + ((SwTxtNode*)this)->SetCalcHiddenCharFlags(); + } + } + break; + + case RES_UPDATE_ATTR: + if( GetNodes().IsDocNodes() && IsTxtNode() ) + { + const sal_uInt16 nTmp = ((SwUpdateAttr*)pNewValue)->nWhichAttr; + if ( RES_ATTRSET_CHG == nTmp ) + { + // anybody wants to do some optimization here? + ((SwTxtNode*)this)->SetCalcHiddenCharFlags(); + } + } + break; + } + + NotifyClients( pOldValue, pNewValue ); +} + +sal_Bool SwCntntNode::InvalidateNumRule() +{ + SwNumRule* pRule = 0; + const SfxPoolItem* pItem; + if( GetNodes().IsDocNodes() && + 0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, sal_True )) && + ((SwNumRuleItem*)pItem)->GetValue().Len() && + 0 != (pRule = GetDoc()->FindNumRulePtr( + ((SwNumRuleItem*)pItem)->GetValue() ) ) ) + { + pRule->SetInvalidRule( sal_True ); + } + return 0 != pRule; +} + +SwCntntFrm *SwCntntNode::getLayoutFrm( const SwRootFrm* _pRoot, + const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm ) const +{ + return (SwCntntFrm*) ::GetFrmOfModify( _pRoot, *(SwModify*)this, FRM_CNTNT, + pPoint, pPos, bCalcFrm ); +} + +SwRect SwCntntNode::FindLayoutRect( const sal_Bool bPrtArea, const Point* pPoint, + const sal_Bool bCalcFrm ) const +{ + SwRect aRet; + SwCntntFrm* pFrm = (SwCntntFrm*)::GetFrmOfModify( 0, *(SwModify*)this, + FRM_CNTNT, pPoint, 0, bCalcFrm ); + if( pFrm ) + aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm(); + return aRet; +} + +SwRect SwCntntNode::FindPageFrmRect( const sal_Bool bPrtArea, const Point* pPoint, + const sal_Bool bCalcFrm ) const +{ + SwRect aRet; + SwFrm* pFrm = ::GetFrmOfModify( 0, *(SwModify*)this, + FRM_CNTNT, pPoint, 0, bCalcFrm ); + if( pFrm && 0 != ( pFrm = pFrm->FindPageFrm() )) + aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm(); + return aRet; +} + +xub_StrLen SwCntntNode::Len() const { return 0; } + + + +SwFmtColl *SwCntntNode::ChgFmtColl( SwFmtColl *pNewColl ) +{ + OSL_ENSURE( pNewColl, "Collectionpointer ist 0." ); + SwFmtColl *pOldColl = GetFmtColl(); + + if( pNewColl != pOldColl ) + { + pNewColl->Add( this ); + + // setze den Parent von unseren Auto-Attributen auf die neue + // Collection: + if( GetpSwAttrSet() ) + AttrSetHandleHelper::SetParent( mpAttrSet, *this, pNewColl, pNewColl ); + +//FEATURE::CONDCOLL + // HACK: hier muss die entsprechend der neuen Vorlage die Bedingungen + // neu ueberprueft werden! + if( sal_True /*pNewColl */ ) + { + SetCondFmtColl( 0 ); + } +//FEATURE::CONDCOLL + + if( !IsModifyLocked() ) + { + SwFmtChg aTmp1( pOldColl ); + SwFmtChg aTmp2( pNewColl ); + SwCntntNode::Modify( &aTmp1, &aTmp2 ); + } + } + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( sal_False ); + } + return pOldColl; +} + + +sal_Bool SwCntntNode::GoNext(SwIndex * pIdx, sal_uInt16 nMode ) const +{ + sal_Bool bRet = sal_True; + if( pIdx->GetIndex() < Len() ) + { + if( !IsTxtNode() ) + (*pIdx)++; + else + { + const SwTxtNode& rTNd = *GetTxtNode(); + xub_StrLen nPos = pIdx->GetIndex(); + if( pBreakIt->GetBreakIter().is() ) + { + sal_Int32 nDone = 0; + sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ? + CharacterIteratorMode::SKIPCELL : + CharacterIteratorMode::SKIPCONTROLCHARACTER; + nPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharacters( rTNd.GetTxt(), nPos, + pBreakIt->GetLocale( rTNd.GetLang( nPos ) ), + nItrMode, 1, nDone ); + + // Check if nPos is inside hidden text range: + if ( CRSR_SKIP_HIDDEN & nMode ) + { + xub_StrLen nHiddenStart; + xub_StrLen nHiddenEnd; + SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd ); + if ( nHiddenStart != STRING_LEN && nHiddenStart != nPos ) + nPos = nHiddenEnd; + } + + if( 1 == nDone ) + *pIdx = nPos; + else + bRet = sal_False; + } + else if( nPos < rTNd.GetTxt().Len() ) + (*pIdx)++; + else + bRet = sal_False; + } + } + else + bRet = sal_False; + return bRet; +} + + +sal_Bool SwCntntNode::GoPrevious(SwIndex * pIdx, sal_uInt16 nMode ) const +{ + sal_Bool bRet = sal_True; + if( pIdx->GetIndex() > 0 ) + { + if( !IsTxtNode() ) + (*pIdx)--; + else + { + const SwTxtNode& rTNd = *GetTxtNode(); + xub_StrLen nPos = pIdx->GetIndex(); + if( pBreakIt->GetBreakIter().is() ) + { + sal_Int32 nDone = 0; + sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ? + CharacterIteratorMode::SKIPCELL : + CharacterIteratorMode::SKIPCONTROLCHARACTER; + nPos = (xub_StrLen)pBreakIt->GetBreakIter()->previousCharacters( rTNd.GetTxt(), nPos, + pBreakIt->GetLocale( rTNd.GetLang( nPos ) ), + nItrMode, 1, nDone ); + + // Check if nPos is inside hidden text range: + if ( CRSR_SKIP_HIDDEN & nMode ) + { + xub_StrLen nHiddenStart; + xub_StrLen nHiddenEnd; + SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd ); + if ( nHiddenStart != STRING_LEN ) + nPos = nHiddenStart; + } + + if( 1 == nDone ) + *pIdx = nPos; + else + bRet = sal_False; + } + else if( nPos ) + (*pIdx)--; + else + bRet = sal_False; + } + } + else + bRet = sal_False; + return bRet; +} + + +/* + * Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom + * Dokument. Die erzeugten Contentframes werden in das entsprechende + * Layout gehaengt. + */ + + +void SwCntntNode::MakeFrms( SwCntntNode& rNode ) +{ + OSL_ENSURE( &rNode != this, + "Kein Contentnode oder Copy-Node und neuer Node identisch." ); + + if( !GetDepends() || &rNode == this ) // gibt es ueberhaupt Frames ?? + return; + + SwFrm *pFrm, *pNew; + SwLayoutFrm *pUpper; + // Frames anlegen fuer Nodes, die vor oder hinter der Tabelle stehen ?? + OSL_ENSURE( FindTableNode() == rNode.FindTableNode(), "Table confusion" ); + + SwNode2Layout aNode2Layout( *this, rNode.GetIndex() ); + + while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, rNode )) ) + { + pNew = rNode.MakeFrm( pUpper ); + pNew->Paste( pUpper, pFrm ); + // #i27138# + // notify accessibility paragraphs objects about changed + // CONTENT_FLOWS_FROM/_TO relation. + // Relation CONTENT_FLOWS_FROM for next paragraph will change + // and relation CONTENT_FLOWS_TO for previous paragraph will change. + if ( pNew->IsTxtFrm() ) + { + ViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() ); + if ( pViewShell && pViewShell->GetLayout() && + pViewShell->GetLayout()->IsAnyShellAccessible() ) + { + pViewShell->InvalidateAccessibleParaFlowRelation( + dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )), + dynamic_cast<SwTxtFrm*>(pNew->FindPrevCnt( true )) ); + } + } + // <-- + } +} + +/* + * Methode loescht fuer den Node alle Ansichten vom + * Dokument. Die Contentframes werden aus dem entsprechenden + * Layout ausgehaengt. + */ + + +void SwCntntNode::DelFrms() +{ + if( !GetDepends() ) + return; + + SwCntntFrm::DelFrms(*this); + if( IsTxtNode() ) + { + ((SwTxtNode*)this)->SetWrong( NULL ); + ((SwTxtNode*)this)->SetWrongDirty( true ); + + ((SwTxtNode*)this)->SetGrammarCheck( NULL ); + ((SwTxtNode*)this)->SetGrammarCheckDirty( true ); + // SMARTTAGS + ((SwTxtNode*)this)->SetSmartTags( NULL ); + ((SwTxtNode*)this)->SetSmartTagDirty( true ); + + ((SwTxtNode*)this)->SetWordCountDirty( true ); + ((SwTxtNode*)this)->SetAutoCompleteWordDirty( true ); + } +} + + +SwCntntNode *SwCntntNode::JoinNext() +{ + return this; +} + + +SwCntntNode *SwCntntNode::JoinPrev() +{ + return this; +} + + + + // erfrage vom Modify Informationen +sal_Bool SwCntntNode::GetInfo( SfxPoolItem& rInfo ) const +{ + switch( rInfo.Which() ) + { + case RES_AUTOFMT_DOCNODE: + if( &GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes ) + { + ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = this; + return sal_False; + } + break; + + case RES_FINDNEARESTNODE: + if( ((SwFmtPageDesc&)GetAttr( RES_PAGEDESC )).GetPageDesc() ) + ((SwFindNearestNode&)rInfo).CheckNode( *this ); + return sal_True; + + case RES_CONTENT_VISIBLE: + { + ((SwPtrMsgPoolItem&)rInfo).pObject = + SwIterator<SwFrm,SwCntntNode>::FirstElement(*this); + } + return sal_False; + } + + return SwModify::GetInfo( rInfo ); +} + + + // setze ein Attribut +sal_Bool SwCntntNode::SetAttr(const SfxPoolItem& rAttr ) +{ + if( !GetpSwAttrSet() ) // lasse von den entsprechenden Nodes die + NewAttrSet( GetDoc()->GetAttrPool() ); // AttrSets anlegen + + OSL_ENSURE( GetpSwAttrSet(), "warum wurde kein AttrSet angelegt?" ); + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( sal_False ); + } + + sal_Bool bRet = sal_False; + // wenn Modify gelockt ist, werden keine Modifies verschickt + if( IsModifyLocked() || + ( !GetDepends() && RES_PARATR_NUMRULE != rAttr.Which() )) + { + bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rAttr ); + } + else + { + SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), + aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); + if( 0 != ( bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rAttr, &aOld, &aNew ) )) + { + SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); + SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); + ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + } + return bRet; +} +#include <svl/itemiter.hxx> + +sal_Bool SwCntntNode::SetAttr( const SfxItemSet& rSet ) +{ + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( sal_False ); + } + + const SfxPoolItem* pFnd = 0; + if( SFX_ITEM_SET == rSet.GetItemState( RES_AUTO_STYLE, sal_False, &pFnd ) ) + { + OSL_ENSURE( rSet.Count() == 1, "SetAutoStyle mixed with other attributes?!" ); + const SwFmtAutoFmt* pTmp = static_cast<const SwFmtAutoFmt*>(pFnd); + + // If there already is an attribute set (usually containing a numbering + // item), we have to merge the attribute of the new set into the old set: + bool bSetParent = true; + if ( GetpSwAttrSet() ) + { + bSetParent = false; + AttrSetHandleHelper::Put( mpAttrSet, *this, *pTmp->GetStyleHandle() ); + } + else + { + mpAttrSet = pTmp->GetStyleHandle(); + } + + if ( bSetParent ) + { + // If the content node has a conditional style, we have to set the + // string item containing the correct conditional style name (the + // style name property has already been set during the import!) + // In case we do not have a conditional style, we make use of the + // fact that nobody else uses the attribute set behind the handle. + // FME 2007-07-10 #i78124# If autostyle does not have a parent, + // the string is empty. + const SfxPoolItem* pNameItem = 0; + if ( 0 != GetCondFmtColl() || + SFX_ITEM_SET != mpAttrSet->GetItemState( RES_FRMATR_STYLE_NAME, sal_False, &pNameItem ) || + 0 == static_cast<const SfxStringItem*>(pNameItem)->GetValue().Len() ) + AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() ); + else + const_cast<SfxItemSet*>(mpAttrSet.get())->SetParent( &GetFmtColl()->GetAttrSet() ); + } + + return sal_True; + } + + if( !GetpSwAttrSet() ) // lasse von den entsprechenden Nodes die + NewAttrSet( GetDoc()->GetAttrPool() ); // AttrSets anlegen + + sal_Bool bRet = sal_False; + // wenn Modify gelockt ist, werden keine Modifies verschickt + if ( IsModifyLocked() || + ( !GetDepends() && + SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_NUMRULE, sal_False ) ) ) + { + // einige Sonderbehandlungen fuer Attribute + bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rSet ); + } + else + { + SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), + aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); + if( 0 != (bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rSet, &aOld, &aNew )) ) + { + // einige Sonderbehandlungen fuer Attribute + SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); + SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); + ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + } + return bRet; +} + +// Nimmt den Hint mit nWhich aus dem Delta-Array + + +sal_Bool SwCntntNode::ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 ) +{ + if( !GetpSwAttrSet() ) + return sal_False; + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( sal_False ); + } + + // wenn Modify gelockt ist, werden keine Modifies verschickt + if( IsModifyLocked() ) + { + sal_uInt16 nDel = 0; + if ( !nWhich2 || nWhich2 < nWhich1 ) + { + std::vector<sal_uInt16> aClearWhichIds; + aClearWhichIds.push_back( nWhich1 ); + nDel = ClearItemsFromAttrSet( aClearWhichIds ); + } + else + nDel = AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, 0, 0 ); + + if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen + mpAttrSet.reset();//DELETEZ( mpAttrSet ); + return 0 != nDel; + } + + // sollte kein gueltiger Bereich definiert sein ? + if( !nWhich2 || nWhich2 < nWhich1 ) + nWhich2 = nWhich1; // dann setze auf 1. Id, nur dieses Item + + SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), + aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); + sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, &aOld, &aNew ); + + if( bRet ) + { + SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); + SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); + ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + + if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen + mpAttrSet.reset();//DELETEZ( mpAttrSet ); + } + return bRet; +} +sal_Bool SwCntntNode::ResetAttr( const SvUShorts& rWhichArr ) +{ + if( !GetpSwAttrSet() ) + return sal_False; + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( sal_False ); + } + + // wenn Modify gelockt ist, werden keine Modifies verschickt + sal_uInt16 nDel = 0; + if( IsModifyLocked() ) + { + std::vector<sal_uInt16> aClearWhichIds; + for( sal_uInt16 n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n ) + aClearWhichIds.push_back( rWhichArr[ n ] ); + + nDel = ClearItemsFromAttrSet( aClearWhichIds ); + } + else + { + SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), + aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); + + for( sal_uInt16 n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n ) + if( AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, rWhichArr[ n ], &aOld, &aNew )) + ++nDel; + + if( nDel ) + { + SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); + SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); + ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + } + } + if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen + mpAttrSet.reset();//DELETEZ( mpAttrSet ); + return 0 != nDel ; +} + + +sal_uInt16 SwCntntNode::ResetAllAttr() +{ + if( !GetpSwAttrSet() ) + return 0; + + if ( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( sal_False ); + } + + // wenn Modify gelockt ist, werden keine Modifies verschickt + if( IsModifyLocked() ) + { + std::vector<sal_uInt16> aClearWhichIds; + aClearWhichIds.push_back(0); + sal_uInt16 nDel = ClearItemsFromAttrSet( aClearWhichIds ); + if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen + mpAttrSet.reset(); // DELETEZ( mpAttrSet ); + return nDel; + } + + SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), + aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); + sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, 0, &aOld, &aNew ); + + if( bRet ) + { + SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); + SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); + ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt + + if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen + mpAttrSet.reset();//DELETEZ( mpAttrSet ); + } + return aNew.Count(); +} + + +sal_Bool SwCntntNode::GetAttr( SfxItemSet& rSet, sal_Bool bInParent ) const +{ + if( rSet.Count() ) + rSet.ClearItem(); + + const SwAttrSet& rAttrSet = GetSwAttrSet(); + if( bInParent ) + return rSet.Set( rAttrSet, sal_True ) ? sal_True : sal_False; + + rSet.Put( rAttrSet ); + return rSet.Count() ? sal_True : sal_False; +} + +sal_uInt16 SwCntntNode::ClearItemsFromAttrSet( const std::vector<sal_uInt16>& rWhichIds ) +{ + sal_uInt16 nRet = 0; + if ( 0 == rWhichIds.size() ) + return nRet; + + OSL_ENSURE( GetpSwAttrSet(), "no item set" ); + SwAttrSet aNewAttrSet( *GetpSwAttrSet() ); + for ( std::vector<sal_uInt16>::const_iterator aIter = rWhichIds.begin(); + aIter != rWhichIds.end(); + ++aIter ) + { + nRet = nRet + aNewAttrSet.ClearItem( *aIter ); + } + if ( nRet ) + AttrSetHandleHelper::GetNewAutoStyle( mpAttrSet, *this, aNewAttrSet ); + + return nRet; +} + +const SfxPoolItem* SwCntntNode::GetNoCondAttr( sal_uInt16 nWhich, + sal_Bool bInParents ) const +{ + const SfxPoolItem* pFnd = 0; + if( pCondColl && pCondColl->GetRegisteredIn() ) + { + if( !GetpSwAttrSet() || ( SFX_ITEM_SET != GetpSwAttrSet()->GetItemState( + nWhich, sal_False, &pFnd ) && bInParents )) + ((SwFmt*)GetRegisteredIn())->GetItemState( nWhich, bInParents, &pFnd ); + } + // undo change of issue #i51029# + // Note: <GetSwAttrSet()> returns <mpAttrSet>, if set, otherwise it returns + // the attribute set of the paragraph style, which is valid for the + // content node - see file <node.hxx> + else + // <-- + { + GetSwAttrSet().GetItemState( nWhich, bInParents, &pFnd ); + } + return pFnd; +} + + // koennen 2 Nodes zusammengefasst werden ? + // in pIdx kann die 2. Position returnt werden. +int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const +{ + const SwNodes& rNds = GetNodes(); + sal_uInt8 nNdType = GetNodeType(); + SwNodeIndex aIdx( *this, 1 ); + + const SwNode* pNd = this; + while( aIdx < rNds.Count()-1 && + (( pNd = &aIdx.GetNode())->IsSectionNode() || + ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ))) + aIdx++; + + if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() ) + return sal_False; + if( IsTxtNode() ) + { // Do not merge strings if the result exceeds the allowed string length + const SwTxtNode* pTxtNd = static_cast<const SwTxtNode*>(this); + sal_uInt64 nSum = pTxtNd->GetTxt().Len(); + pTxtNd = static_cast<const SwTxtNode*>(pNd); + nSum += pTxtNd->GetTxt().Len(); + if( nSum > STRING_LEN ) + return sal_False; + } + if( pIdx ) + *pIdx = aIdx; + return sal_True; +} + + + // koennen 2 Nodes zusammengefasst werden ? + // in pIdx kann die 2. Position returnt werden. +int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const +{ + sal_uInt8 nNdType = GetNodeType(); + SwNodeIndex aIdx( *this, -1 ); + + const SwNode* pNd = this; + while( aIdx.GetIndex() && + (( pNd = &aIdx.GetNode())->IsSectionNode() || + ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ))) + aIdx--; + + if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() ) + return sal_False; + if( pIdx ) + *pIdx = aIdx; + return sal_True; +} + + +//FEATURE::CONDCOLL + + +void SwCntntNode::SetCondFmtColl( SwFmtColl* pColl ) +{ + if( (!pColl && pCondColl) || ( pColl && !pCondColl ) || + ( pColl && pColl != pCondColl->GetRegisteredIn() ) ) + { + SwFmtColl* pOldColl = GetCondFmtColl(); + delete pCondColl; + if( pColl ) + pCondColl = new SwDepend( this, pColl ); + else + pCondColl = 0; + + if( GetpSwAttrSet() ) + { + AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() ); + } + + if( !IsModifyLocked() ) + { + SwFmtChg aTmp1( pOldColl ? pOldColl : GetFmtColl() ); + SwFmtChg aTmp2( pColl ? pColl : GetFmtColl() ); + NotifyClients( &aTmp1, &aTmp2 ); + } + if( IsInCache() ) + { + SwFrm::GetCache().Delete( this ); + SetInCache( sal_False ); + } + } +} + + +sal_Bool SwCntntNode::IsAnyCondition( SwCollCondition& rTmp ) const +{ + const SwNodes& rNds = GetNodes(); + { + int nCond = 0; + const SwStartNode* pSttNd = StartOfSectionNode(); + while( pSttNd ) + { + switch( pSttNd->GetNodeType() ) + { + case ND_TABLENODE: nCond = PARA_IN_TABLEBODY; break; + case ND_SECTIONNODE: nCond = PARA_IN_SECTION; break; + + default: + switch( pSttNd->GetStartNodeType() ) + { + case SwTableBoxStartNode: + { + nCond = PARA_IN_TABLEBODY; + const SwTableNode* pTblNd = pSttNd->FindTableNode(); + const SwTableBox* pBox; + if( pTblNd && 0 != ( pBox = pTblNd->GetTable(). + GetTblBox( pSttNd->GetIndex() ) ) && pBox && + pBox->IsInHeadline( &pTblNd->GetTable() ) ) + nCond = PARA_IN_TABLEHEAD; + } + break; + case SwFlyStartNode: nCond = PARA_IN_FRAME; break; + case SwFootnoteStartNode: + { + nCond = PARA_IN_FOOTENOTE; + const SwFtnIdxs& rFtnArr = rNds.GetDoc()->GetFtnIdxs(); + const SwTxtFtn* pTxtFtn; + const SwNode* pSrchNd = pSttNd; + + for( sal_uInt16 n = 0; n < rFtnArr.Count(); ++n ) + if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() && + pSrchNd == &pTxtFtn->GetStartNode()->GetNode() ) + { + if( pTxtFtn->GetFtn().IsEndNote() ) + nCond = PARA_IN_ENDNOTE; + break; + } + } + break; + case SwHeaderStartNode: nCond = PARA_IN_HEADER; break; + case SwFooterStartNode: nCond = PARA_IN_FOOTER; break; + case SwNormalStartNode: break; + } + } + + if( nCond ) + { + rTmp.SetCondition( (Master_CollConditions)nCond, 0 ); + return sal_True; + } + pSttNd = pSttNd->GetIndex() + ? pSttNd->StartOfSectionNode() + : 0; + } + } + + { + sal_uInt16 nPos; + const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); + if( rOutlNds.Count() ) + { + if( !rOutlNds.Seek_Entry( (SwCntntNode*)this, &nPos ) && nPos ) + --nPos; + if( nPos < rOutlNds.Count() && + rOutlNds[ nPos ]->GetIndex() < GetIndex() ) + { + SwTxtNode* pOutlNd = rOutlNds[ nPos ]->GetTxtNode(); + + if( pOutlNd->IsOutline()) + { + rTmp.SetCondition( PARA_IN_OUTLINE, pOutlNd->GetAttrOutlineLevel() - 1 ); + return sal_True; + } + } + } + } + + return sal_False; +} + + +void SwCntntNode::ChkCondColl() +{ + // zur Sicherheit abfragen + if( RES_CONDTXTFMTCOLL == GetFmtColl()->Which() ) + { + SwCollCondition aTmp( 0, 0, 0 ); + const SwCollCondition* pCColl; + + bool bDone = false; + + if( IsAnyCondition( aTmp )) + { + pCColl = static_cast<SwConditionTxtFmtColl*>(GetFmtColl()) + ->HasCondition( aTmp ); + + if (pCColl) + { + SetCondFmtColl( pCColl->GetTxtFmtColl() ); + bDone = true; + } + } + + if (!bDone) + { + if( IsTxtNode() && ((SwTxtNode*)this)->GetNumRule()) + { + // steht in einer Numerierung + // welcher Level? + aTmp.SetCondition( PARA_IN_LIST, + ((SwTxtNode*)this)->GetActualListLevel() ); + pCColl = ((SwConditionTxtFmtColl*)GetFmtColl())-> + HasCondition( aTmp ); + } + else + pCColl = 0; + + if( pCColl ) + SetCondFmtColl( pCColl->GetTxtFmtColl() ); + else if( pCondColl ) + SetCondFmtColl( 0 ); + } + } +} + +// #i42921# +short SwCntntNode::GetTextDirection( const SwPosition& rPos, + const Point* pPt ) const +{ + short nRet = -1; + + Point aPt; + if( pPt ) + aPt = *pPt; + + // #i72024# - No format of the frame, because this can cause recursive layout actions + SwFrm* pFrm = getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, &rPos, sal_False ); + + if ( pFrm ) + { + if ( pFrm->IsVertical() ) + { + if ( pFrm->IsRightToLeft() ) + nRet = FRMDIR_VERT_TOP_LEFT; + else + nRet = FRMDIR_VERT_TOP_RIGHT; + } + else + { + if ( pFrm->IsRightToLeft() ) + nRet = FRMDIR_HORI_RIGHT_TOP; + else + nRet = FRMDIR_HORI_LEFT_TOP; + } + } + + + return nRet; +} +// <-- + +SwOLENodes* SwCntntNode::CreateOLENodesArray( const SwFmtColl& rColl, bool bOnlyWithInvalidSize ) +{ + SwOLENodes *pNodes = 0; + SwIterator<SwCntntNode,SwFmtColl> aIter( rColl ); + for( SwCntntNode* pNd = aIter.First(); pNd; pNd = aIter.Next() ) + { + SwOLENode *pONd = pNd->GetOLENode(); + if ( pONd && (!bOnlyWithInvalidSize || pONd->IsOLESizeInvalid()) ) + { + if ( !pNodes ) + pNodes = new SwOLENodes; + pNodes->Insert( pONd, pNodes->Count() ); + } + } + + return pNodes; +} + +//FEATURE::CONDCOLL +// Metoden aus Node.hxx - erst hier ist der TxtNode bekannt !! +// os: nur fuer ICC, da der zum optimieren zu dumm ist +#ifdef ICC +SwTxtNode *SwNode::GetTxtNode() +{ + return ND_TEXTNODE == nNodeType ? (SwTxtNode*)this : 0; +} +const SwTxtNode *SwNode::GetTxtNode() const +{ + return ND_TEXTNODE == nNodeType ? (const SwTxtNode*)this : 0; +} +#endif + +/* + * Document Interface Access + */ +const IDocumentSettingAccess* SwNode::getIDocumentSettingAccess() const { return GetDoc(); } +const IDocumentDeviceAccess* SwNode::getIDocumentDeviceAccess() const { return GetDoc(); } +const IDocumentMarkAccess* SwNode::getIDocumentMarkAccess() const { return GetDoc()->getIDocumentMarkAccess(); } +const IDocumentRedlineAccess* SwNode::getIDocumentRedlineAccess() const { return GetDoc(); } +const IDocumentStylePoolAccess* SwNode::getIDocumentStylePoolAccess() const { return GetDoc(); } +const IDocumentLineNumberAccess* SwNode::getIDocumentLineNumberAccess() const { return GetDoc(); } +const IDocumentDrawModelAccess* SwNode::getIDocumentDrawModelAccess() const { return GetDoc(); } +const IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() const { return GetDoc(); } +IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() { return GetDoc(); } +const IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() const { return GetDoc(); } +IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() { return GetDoc(); } +const IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() const { return GetDoc(); } +IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() { return GetDoc(); } +IDocumentContentOperations* SwNode::getIDocumentContentOperations() { return GetDoc(); } +IStyleAccess& SwNode::getIDocumentStyleAccess() { return GetDoc()->GetIStyleAccess(); } +// #i83479# +IDocumentListItems& SwNode::getIDocumentListItems() +{ + return *GetDoc(); +} + +sal_Bool SwNode::IsInRedlines() const +{ + const SwDoc * pDoc = GetDoc(); + sal_Bool bResult = sal_False; + + if (pDoc != NULL) + bResult = pDoc->IsInRedlines(*this); + + return bResult; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |