| /************************************************************** |
| * |
| * 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/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()); |
| ASSERT( pAttrSet, "no SwAttrSet" ) |
| ASSERT( 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 |
| |* |
| |* Ersterstellung |
| |* VER0100 vb 901214 |
| |* |
| |* Aenderung: JP 11.08.93 |
| |* keine Rekursion mehr !! |
| |* |
| *******************************************************************/ |
| |
| |
| 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 |
| |* |
| |* Ersterstellung |
| |* VER0100 vb 901214 |
| |* |
| |* Stand |
| |* VER0100 vb 901214 |
| |* |
| *******************************************************************/ |
| |
| #ifdef DBG_UTIL |
| 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; |
| } |
| |
| #ifdef DBG_UTIL |
| 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; |
| } |
| |
| #ifdef DBG_UTIL |
| 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 |
| { |
| // OD 18.03.2003 #106329# |
| 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(); |
| // OD 18.03.2003 #106329# |
| 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() ) |
| { |
| ASSERT( !this, "Fly-Section but no format found" ); |
| return NULL; |
| } |
| } |
| } |
| } |
| // 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 |
| ASSERT( 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(); |
| // OD 18.03.2003 #106329# |
| 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() ) |
| //->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei |
| ->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 ); |
| // --> OD 2007-06-04 #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; |
| // --> OD 2007-06-04 #i77805# |
| // skip section start and end nodes |
| // aIdx += 2; |
| 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 |
| |* Ersterstellung |
| |* VER0100 vb 901214 |
| |* |
| |* Stand |
| |* VER0100 vb 901214 |
| |* |
| *******************************************************************/ |
| |
| |
| 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! |
| |* |
| |* Ersterstellung |
| |* VER0100 vb 901214 |
| |* |
| |* Stand |
| |* VER0100 vb 901214 |
| |* |
| *******************************************************************/ |
| |
| |
| 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 ) |
| #ifdef OLD_INDEX |
| ,SwIndexReg(2) |
| #endif |
| { |
| } |
| |
| |
| 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(sal_True, sal_False); |
| |
| 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 ) |
| { |
| ASSERT( 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 ) |
| { |
| ASSERT( &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 ?? |
| ASSERT( 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 ); |
| // --> OD 2005-12-01 #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. |
| */ |
| |
| |
| //Solution:Add a input param to identify if the acc table should be disposed. |
| //add a flag(bNeedDel) to indicate whether to del corresponding frm even in doc loading process, |
| //void SwCntntNode::DelFrms() |
| void SwCntntNode::DelFrms( sal_Bool /* bNeedDel */, sal_Bool bIsDisposeAccTable ) |
| { |
| if( !GetDepends() ) |
| return; |
| |
| SwClientIter aIter( *this ); |
| SwCntntFrm *pFrm; |
| |
| for( pFrm = (SwCntntFrm*)aIter.First( TYPE(SwCntntFrm)); pFrm; |
| pFrm = (SwCntntFrm*)aIter.Next() ) |
| { |
| // --> OD 2005-12-01 #i27138# |
| // notify accessibility paragraphs objects about changed |
| // CONTENT_FLOWS_FROM/_TO relation. |
| // Relation CONTENT_FLOWS_FROM for current next paragraph will change |
| // and relation CONTENT_FLOWS_TO for current previous paragraph will change. |
| if ( pFrm->IsTxtFrm() ) |
| { |
| ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() ); |
| if ( pViewShell && pViewShell->GetLayout() && |
| pViewShell->GetLayout()->IsAnyShellAccessible() ) |
| { |
| pViewShell->InvalidateAccessibleParaFlowRelation( |
| dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )), |
| dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) ); |
| } |
| } |
| // <-- |
| if( pFrm->HasFollow() ) |
| pFrm->GetFollow()->_SetIsFollow( pFrm->IsFollow() ); |
| if( pFrm->IsFollow() ) |
| { |
| SwCntntFrm* pMaster = (SwTxtFrm*)pFrm->FindMaster(); |
| pMaster->SetFollow( pFrm->GetFollow() ); |
| pFrm->_SetIsFollow( sal_False ); |
| } |
| pFrm->SetFollow( 0 );//Damit er nicht auf dumme Gedanken kommt. |
| //Andernfalls kann es sein, dass ein Follow |
| //vor seinem Master zerstoert wird, der Master |
| //greift dann ueber den ungueltigen |
| //Follow-Pointer auf fremdes Memory zu. |
| //Die Kette darf hier zerknauscht werden, weil |
| //sowieso alle zerstoert werden. |
| if( pFrm->GetUpper() && pFrm->IsInFtn() && !pFrm->GetIndNext() && |
| !pFrm->GetIndPrev() ) |
| { |
| SwFtnFrm *pFtn = pFrm->FindFtnFrm(); |
| ASSERT( pFtn, "You promised a FtnFrm?" ); |
| SwCntntFrm* pCFrm; |
| if( !pFtn->GetFollow() && !pFtn->GetMaster() && |
| 0 != ( pCFrm = pFtn->GetRefFromAttr()) && pCFrm->IsFollow() ) |
| { |
| ASSERT( pCFrm->IsTxtFrm(), "NoTxtFrm has Footnote?" ); |
| ((SwTxtFrm*)pCFrm->FindMaster())->Prepare( PREP_FTN_GONE ); |
| } |
| } |
| //Solution:Set acc table dispose state |
| pFrm->SetAccTableDispose( bIsDisposeAccTable ); |
| //End Added |
| pFrm->Cut(); |
| //Solution:Set acc table dispose state to default value |
| pFrm->SetAccTableDispose( sal_True ); |
| delete pFrm; |
| } |
| 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; |
| // --> OD 2008-02-19 #refactorlists# |
| // case RES_GETNUMNODES: |
| // // #111955# only numbered nodes in rInfo |
| // if( IsTxtNode()) |
| // { |
| // SwTxtNode * pTxtNode = (SwTxtNode*)this; |
| // pItem = (SwNumRuleItem*)GetNoCondAttr(RES_PARATR_NUMRULE, sal_True ); |
| |
| // if (0 != pItem && |
| // pItem->GetValue().Len() && |
| // pItem->GetValue() == ((SwNumRuleInfo&)rInfo).GetName() && |
| // GetNodes().IsDocNodes()) |
| // { |
| // ((SwNumRuleInfo&)rInfo).AddNode( *pTxtNode ); |
| // } |
| // } |
| |
| // return sal_True; |
| // <-- |
| |
| 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 |
| |
| ASSERT( 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 ) ) |
| { |
| ASSERT( 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; |
| |
| ASSERT( 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 ); |
| } |
| // --> OD 2005-10-25 #126347# - 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 ); |
| } |
| } |
| } |
| |
| // --> OD 2005-02-21 #i42921# |
| short SwCntntNode::GetTextDirection( const SwPosition& rPos, |
| const Point* pPt ) const |
| { |
| short nRet = -1; |
| |
| Point aPt; |
| if( pPt ) |
| aPt = *pPt; |
| |
| // --> OD 2007-01-10 #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(); } |
| // --> OD 2007-10-31 #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; |
| } |