diff options
Diffstat (limited to 'binfilter/bf_sw/source/core/docnode')
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/makefile.mk | 84 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_ndarr.cxx | 73 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_ndcopy.cxx | 563 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_ndindex.cxx | 156 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_ndnotxt.cxx | 203 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_ndnum.cxx | 371 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_ndsect.cxx | 940 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_ndtbl.cxx | 920 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_ndtbl1.cxx | 407 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_node.cxx | 1351 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_node2lay.cxx | 360 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_nodes.cxx | 1421 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_section.cxx | 1150 | ||||
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_swbaslnk.cxx | 478 |
14 files changed, 8477 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/docnode/makefile.mk b/binfilter/bf_sw/source/core/docnode/makefile.mk new file mode 100644 index 000000000000..86c4fdc61eee --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/makefile.mk @@ -0,0 +1,84 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXTERNAL_WARNINGS_NOT_ERRORS := TRUE + +PRJ=..$/..$/..$/.. +BFPRJ=..$/..$/.. + +PRJNAME=binfilter +TARGET=sw_docnode + +NO_HIDS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/inc$/bf_sw$/swpre.mk +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/bf_sw$/sw.mk +INC+= -I$(PRJ)$/inc$/bf_sw +.IF "$(GUI)$(COM)" == "WINMSC" +LIBFLAGS=/NOI /NOE /PAGE:512 +.ENDIF + + +# --- Files -------------------------------------------------------- + +CXXFILES = \ + sw_ndindex.cxx \ + sw_ndcopy.cxx \ + sw_ndnotxt.cxx \ + sw_ndnum.cxx \ + sw_ndsect.cxx \ + sw_ndtbl.cxx \ + sw_ndtbl1.cxx \ + sw_node.cxx \ + sw_node2lay.cxx \ + sw_nodes.cxx \ + sw_section.cxx \ + sw_swbaslnk.cxx + + + +SLOFILES = \ + $(SLO)$/sw_ndindex.obj \ + $(SLO)$/sw_ndcopy.obj \ + $(SLO)$/sw_ndnotxt.obj \ + $(SLO)$/sw_ndnum.obj \ + $(SLO)$/sw_ndsect.obj \ + $(SLO)$/sw_ndtbl.obj \ + $(SLO)$/sw_ndtbl1.obj \ + $(SLO)$/sw_node.obj \ + $(SLO)$/sw_node2lay.obj \ + $(SLO)$/sw_nodes.obj \ + $(SLO)$/sw_section.obj \ + $(SLO)$/sw_swbaslnk.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/binfilter/bf_sw/source/core/docnode/sw_ndarr.cxx b/binfilter/bf_sw/source/core/docnode/sw_ndarr.cxx new file mode 100644 index 000000000000..677da90cd4ae --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_ndarr.cxx @@ -0,0 +1,73 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <index.hxx> +#include <ndarr.hxx> +namespace binfilter { + + +void SwNds::Insert(const SwNodePtr &aElement, const SwIndex & aPos) +{ + theArr.Insert((const ElementPtr&) aElement, aPos.GetIndex()); + SwIndexReg::Update(aPos, 1); +} + +void SwNds::Insert(const SwNodePtr* pElement, USHORT nLen, const SwIndex & aPos) +{ + theArr.Insert((const ElementPtr*) pElement, nLen, aPos.GetIndex()); + SwIndexReg::Update(aPos, nLen); +} + +void SwNds::Remove(const SwIndex & aPos, USHORT nLen) +{ + if(nLen) + { + theArr.Remove(aPos.GetIndex(), nLen); + SwIndexReg::Update(aPos, nLen, TRUE); + } +} + +BOOL SwNds::Move( const SwIndex & rOldPos, const SwIndex & rNewPos ) +{ + register USHORT nDelPos = rOldPos.GetIndex(), + nInsPos = rNewPos.GetIndex(); + if( nDelPos == nInsPos || nDelPos +1 == nInsPos ) + return FALSE; + theArr.Move( nDelPos, nInsPos ); + SwIndexReg::MoveIdx( rOldPos, rNewPos ); + return TRUE; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_ndcopy.cxx b/binfilter/bf_sw/source/core/docnode/sw_ndcopy.cxx new file mode 100644 index 000000000000..84fd550cfd82 --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_ndcopy.cxx @@ -0,0 +1,563 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#define _ZFORLIST_DECLARE_TABLE +#include <hintids.hxx> + + + +#include <fmtanchr.hxx> +#include <fmtcntnt.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> + +#include <errhdl.hxx> + +#include <ndtxt.hxx> +#include <ddefld.hxx> +#include <mvsave.hxx> +#include <cellatr.hxx> +#include <swtblfmt.hxx> +#include <swddetbl.hxx> +#include <docary.hxx> +#include <fmtcnct.hxx> +#include <redline.hxx> +namespace binfilter { + +// Struktur fuer das Mappen von alten und neuen Frame-Formaten an den +// Boxen und Lines einer Tabelle + +/*N*/ struct _MapTblFrmFmt +/*N*/ { +/*N*/ const SwFrmFmt *pOld, *pNew; +/*N*/ _MapTblFrmFmt( const SwFrmFmt *pOldFmt, const SwFrmFmt*pNewFmt ) +/*N*/ : pOld( pOldFmt ), pNew( pNewFmt ) +/*N*/ {} +/*N*/ }; + +/*N*/ SV_DECL_VARARR( _MapTblFrmFmts, _MapTblFrmFmt, 0, 10 )//STRIP008 ; +/*N*/ SV_IMPL_VARARR( _MapTblFrmFmts, _MapTblFrmFmt ); + +/*N*/ SwCntntNode* SwTxtNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const +/*N*/ { +/*N*/ // the Copy-Textnode is the Node with the Text, the Copy-Attrnode is the +/*N*/ // node with the collection and hard attributes. Normally ist the same +/*N*/ // node, but if insert a glossary without formatting, then the Attrnode +/*N*/ // is the prev node of the destionation position in dest. document. +/*N*/ SwTxtNode* pCpyTxtNd = (SwTxtNode*)this; +/*N*/ SwTxtNode* pCpyAttrNd = pCpyTxtNd; +/*N*/ +/*N*/ // kopiere die Formate in das andere Dokument: +/*N*/ SwTxtFmtColl* pColl = 0; +/*N*/ if( pDoc->IsInsOnlyTextGlossary() ) +/*N*/ { +/*?*/ SwNodeIndex aIdx( rIdx, -1 ); +/*?*/ if( aIdx.GetNode().IsTxtNode() ) +/*?*/ { +/*?*/ pCpyAttrNd = aIdx.GetNode().GetTxtNode(); +/*?*/ pColl = &pCpyAttrNd->GetTxtColl()->GetNextTxtFmtColl(); +/*?*/ } +/*N*/ } +/*N*/ if( !pColl ) +/*N*/ pColl = pDoc->CopyTxtColl( *GetTxtColl() ); +/*N*/ +/*N*/ SwTxtNode* pTxtNd = pDoc->GetNodes().MakeTxtNode( rIdx, pColl ); +/*N*/ +/*N*/ // kopiere Attribute/Text +/*N*/ if( !pCpyAttrNd->GetpSwAttrSet() ) +/*N*/ // wurde ein AttrSet fuer die Numerierung angelegt, so loesche diesen! +/*N*/ pTxtNd->ResetAllAttr(); +/*N*/ +/*N*/ // if Copy-Textnode unequal to Copy-Attrnode, then copy first +/*N*/ // the attributes into the new Node. +/*N*/ if( pCpyAttrNd != pCpyTxtNd ) +/*N*/ { +/*?*/ pCpyAttrNd->CopyAttr( pTxtNd, 0, 0 ); +/*?*/ if( pCpyAttrNd->GetpSwAttrSet() ) +/*?*/ { +/*?*/ SwAttrSet aSet( *pCpyAttrNd->GetpSwAttrSet() ); +/*?*/ aSet.ClearItem( RES_PAGEDESC ); +/*?*/ aSet.ClearItem( RES_BREAK ); +/*?*/ aSet.CopyToModify( *pTxtNd ); +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ // ??? reicht das ??? was ist mit PostIts/Feldern/FeldTypen ??? +/*N*/ pCpyTxtNd->Copy( pTxtNd, SwIndex( pCpyTxtNd ), pCpyTxtNd->GetTxt().Len() ); +/*N*/ +/*N*/ if( pCpyAttrNd->GetNum() ) +/*N*/ pTxtNd->UpdateNum( *pCpyAttrNd->GetNum() ); +/*N*/ +/*N*/ //FEATURE::CONDCOLL +/*N*/ if( RES_CONDTXTFMTCOLL == pColl->Which() ) +/*N*/ pTxtNd->ChkCondColl(); +/*N*/ //FEATURE::CONDCOLL +/*N*/ +/*N*/ return pTxtNd; +/*N*/ } + + +/*N*/ BOOL lcl_SrchNew( const _MapTblFrmFmt& rMap, void * pPara ) +/*N*/ { +/*N*/ if( rMap.pOld != *(const SwFrmFmt**)pPara ) +/*N*/ return TRUE; +/*N*/ *((const SwFrmFmt**)pPara) = rMap.pNew; +/*N*/ return FALSE; // abbrechen, Pointer gefunden +/*N*/ } + + +/*N*/ struct _CopyTable +/*N*/ { +/*N*/ SwDoc* pDoc; +/*N*/ ULONG nOldTblSttIdx; +/*N*/ _MapTblFrmFmts& rMapArr; +/*N*/ SwTableLine* pInsLine; +/*N*/ SwTableBox* pInsBox; +/*N*/ SwTableNode *pTblNd; +/*N*/ const SwTable *pOldTable; +/*N*/ +/*N*/ _CopyTable( SwDoc* pDc, _MapTblFrmFmts& rArr, ULONG nOldStt, +/*N*/ SwTableNode& rTblNd, const SwTable* pOldTbl ) +/*N*/ : pDoc(pDc), pTblNd(&rTblNd), nOldTblSttIdx(nOldStt), +/*N*/ rMapArr(rArr), pOldTable( pOldTbl ), pInsLine(0), pInsBox(0) +/*N*/ {} +/*N*/ }; + +/*N*/ BOOL lcl_CopyTblBox( const SwTableBox*& rpBox, void* pPara ); + +/*N*/ BOOL lcl_CopyTblLine( const SwTableLine*& rpLine, void* pPara ); + +/*N*/ BOOL lcl_CopyTblBox( const SwTableBox*& rpBox, void* pPara ) +/*N*/ { +/*N*/ _CopyTable* pCT = (_CopyTable*)pPara; +/*N*/ +/*N*/ SwTableBoxFmt* pBoxFmt = (SwTableBoxFmt*)rpBox->GetFrmFmt(); +/*N*/ pCT->rMapArr.ForEach( lcl_SrchNew, &pBoxFmt ); +/*N*/ if( pBoxFmt == rpBox->GetFrmFmt() ) // ein neues anlegen ?? +/*N*/ { +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( SFX_ITEM_SET == pBoxFmt->GetItemState( RES_BOXATR_FORMULA, FALSE, +/*N*/ &pItem ) && ((SwTblBoxFormula*)pItem)->IsIntrnlName() ) +/*N*/ { +/*?*/ ((SwTblBoxFormula*)pItem)->PtrToBoxNm( pCT->pOldTable ); +/*N*/ } +/*N*/ +/*N*/ pBoxFmt = pCT->pDoc->MakeTableBoxFmt(); +/*N*/ pBoxFmt->CopyAttrs( *rpBox->GetFrmFmt() ); +/*N*/ +/*N*/ if( rpBox->GetSttIdx() ) +/*N*/ { +/*N*/ SvNumberFormatter* pN = pCT->pDoc->GetNumberFormatter( FALSE ); +/*N*/ if( pN && pN->HasMergeFmtTbl() && SFX_ITEM_SET == pBoxFmt-> +/*N*/ GetItemState( RES_BOXATR_FORMAT, FALSE, &pItem ) ) +/*N*/ { +/*?*/ ULONG nOldIdx = ((SwTblBoxNumFormat*)pItem)->GetValue(); +/*?*/ ULONG nNewIdx = pN->GetMergeFmtIndex( nOldIdx ); +/*?*/ if( nNewIdx != nOldIdx ) +/*?*/ pBoxFmt->SetAttr( SwTblBoxNumFormat( nNewIdx )); +/*?*/ +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pCT->rMapArr.Insert( _MapTblFrmFmt( rpBox->GetFrmFmt(), pBoxFmt ), +/*N*/ pCT->rMapArr.Count() ); +/*N*/ } +/*N*/ +/*N*/ USHORT nLines = rpBox->GetTabLines().Count(); +/*N*/ SwTableBox* pNewBox; +/*N*/ if( nLines ) +/*?*/ pNewBox = new SwTableBox( pBoxFmt, nLines, pCT->pInsLine ); +/*N*/ else +/*N*/ { +/*N*/ SwNodeIndex aNewIdx( *pCT->pTblNd, +/*N*/ rpBox->GetSttIdx() - pCT->nOldTblSttIdx ); +/*N*/ ASSERT( aNewIdx.GetNode().IsStartNode(), "Index nicht auf einem StartNode" ); +/*N*/ pNewBox = new SwTableBox( pBoxFmt, aNewIdx, pCT->pInsLine ); +/*N*/ } +/*N*/ +/*N*/ pCT->pInsLine->GetTabBoxes().C40_INSERT( SwTableBox, pNewBox, +/*N*/ pCT->pInsLine->GetTabBoxes().Count() ); +/*N*/ +/*N*/ if( nLines ) +/*N*/ { +/*?*/ _CopyTable aPara( *pCT ); +/*?*/ aPara.pInsBox = pNewBox; +/*?*/ ((SwTableBox*)rpBox)->GetTabLines().ForEach( &lcl_CopyTblLine, &aPara ); +/*N*/ } +/*N*/ else if( pNewBox->IsInHeadline( &pCT->pTblNd->GetTable() )) +/*N*/ // in der HeadLine sind die Absaetze mit BedingtenVorlage anzupassen +/*N*/ pNewBox->GetSttNd()->CheckSectionCondColl(); +/*N*/ return TRUE; +/*N*/ } + +/*N*/ BOOL lcl_CopyTblLine( const SwTableLine*& rpLine, void* pPara ) +/*N*/ { +/*N*/ _CopyTable* pCT = (_CopyTable*)pPara; +/*N*/ SwTableLineFmt* pLineFmt = (SwTableLineFmt*)rpLine->GetFrmFmt(); +/*N*/ pCT->rMapArr.ForEach( lcl_SrchNew, &pLineFmt ); +/*N*/ if( pLineFmt == rpLine->GetFrmFmt() ) // ein neues anlegen ?? +/*N*/ { +/*N*/ pLineFmt = pCT->pDoc->MakeTableLineFmt(); +/*N*/ pLineFmt->CopyAttrs( *rpLine->GetFrmFmt() ); +/*N*/ pCT->rMapArr.Insert( _MapTblFrmFmt( rpLine->GetFrmFmt(), pLineFmt ), +/*N*/ pCT->rMapArr.Count()); +/*N*/ } +/*N*/ SwTableLine* pNewLine = new SwTableLine( pLineFmt, +/*N*/ rpLine->GetTabBoxes().Count(), pCT->pInsBox ); +/*N*/ // die neue Zeile in die Tabelle eintragen +/*N*/ if( pCT->pInsBox ) +/*N*/ { +/*?*/ pCT->pInsBox->GetTabLines().C40_INSERT( SwTableLine, pNewLine, +/*?*/ pCT->pInsBox->GetTabLines().Count() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pCT->pTblNd->GetTable().GetTabLines().C40_INSERT( SwTableLine, pNewLine, +/*N*/ pCT->pTblNd->GetTable().GetTabLines().Count() ); +/*N*/ } +/*N*/ pCT->pInsLine = pNewLine; +/*N*/ ((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &lcl_CopyTblBox, pCT ); +/*N*/ return TRUE; +/*N*/ } + +/*N*/ SwTableNode* SwTableNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const +/*N*/ { +/*N*/ // in welchen Array steht ich denn Nodes, UndoNodes ?? +/*N*/ SwNodes& rNds = (SwNodes&)GetNodes(); +/*N*/ +/*N*/ if( pDoc->IsIdxInTbl( rIdx ) ) +/*N*/ // zur Zeit keine Tabelle in Tabelle kopieren unterstuetzen +/*N*/ // (sprich: Text + Tabelle + Text ) +/*?*/ return 0; +/*N*/ +/*N*/ { +/*N*/ // nicht in Fussnoten kopieren !! +/* +!! Mal ohne Frames + SwCntntNode* pCNd = pDoc->GetNodes()[ rIdx ]->GetCntntNode(); + SwFrm* pFrm; + if( (pCNd && 0 != ( pFrm = pCNd->GetFrm())) + ? pFrm->FindFtnFrm() + : rIdx < pDoc->GetNodes().EndOfInserts && + pDoc->GetNodes()[pDoc->GetNodes().EndOfInserts]->StartOfSection() + < rIdx ) +*/ +/*N*/ if( rIdx < pDoc->GetNodes().GetEndOfInserts().GetIndex() && +/*N*/ rIdx >= pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() ) +/*?*/ return 0; +/*N*/ } +/*N*/ +/*N*/ // das TableFrmFmt kopieren +/*N*/ String sTblName( GetTable().GetFrmFmt()->GetName() ); +/*N*/ if( !pDoc->IsCopyIsMove() ) +/*N*/ { +/*N*/ const SwFrmFmts& rTblFmts = *pDoc->GetTblFrmFmts(); +/*N*/ for( USHORT n = rTblFmts.Count(); n; ) +/*N*/ if( rTblFmts[ --n ]->GetName() == sTblName ) +/*N*/ { +/*N*/ sTblName = pDoc->GetUniqueTblName(); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwFrmFmt* pTblFmt = pDoc->MakeTblFrmFmt( sTblName, pDoc->GetDfltFrmFmt() ); +/*N*/ pTblFmt->CopyAttrs( *GetTable().GetFrmFmt() ); +/*N*/ SwTableNode* pTblNd = new SwTableNode( rIdx ); +/*N*/ SwEndNode* pEndNd = new SwEndNode( rIdx, *pTblNd ); +/*N*/ SwNodeIndex aInsPos( *pEndNd ); +/*N*/ +/*N*/ SwTable& rTbl = (SwTable&)pTblNd->GetTable(); +/*N*/ pTblFmt->Add( &rTbl ); // das Frame-Format setzen +/*N*/ +/*N*/ rTbl.SetHeadlineRepeat( GetTable().IsHeadlineRepeat() ); +/*N*/ rTbl.SetTblChgMode( GetTable().GetTblChgMode() ); +/*N*/ +/*N*/ SwDDEFieldType* pDDEType = 0; +/*N*/ if( IS_TYPE( SwDDETable, &GetTable() )) +/*N*/ { +/*?*/ // es wird eine DDE-Tabelle kopiert +/*?*/ // ist im neuen Dokument ueberhaupt der FeldTyp vorhanden ? +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pDDEType = ((SwDDETable&)GetTable()).GetDDEFldType(); +/*N*/ } +/*N*/ // dann kopiere erstmal den Inhalt der Tabelle, die Zuordnung der +/*N*/ // Boxen/Lines und das anlegen der Frames erfolgt spaeter +/*N*/ SwNodeRange aRg( *this, +1, *EndOfSectionNode() ); // (wo stehe in denn nun ??) +/*N*/ rNds._Copy( aRg, aInsPos, FALSE ); +/*N*/ +/*N*/ // Sonderbehandlung fuer eine einzelne Box +/*N*/ if( 1 == GetTable().GetTabSortBoxes().Count() ) +/*N*/ { +/*?*/ aRg.aStart.Assign( *pTblNd, 1 ); +/*?*/ aRg.aEnd.Assign( *pTblNd->EndOfSectionNode() ); +/*?*/ pDoc->GetNodes().SectionDown( &aRg, SwTableBoxStartNode ); +/*N*/ } +/*N*/ +/*N*/ // loesche alle Frames vom kopierten Bereich, diese werden beim +/*N*/ // erzeugen des TableFrames angelegt ! +/*N*/ pTblNd->DelFrms(); +/*N*/ +/*N*/ _MapTblFrmFmts aMapArr; +/*N*/ _CopyTable aPara( pDoc, aMapArr, GetIndex(), *pTblNd, &GetTable() ); +/*N*/ +/*N*/ ((SwTable&)GetTable()).GetTabLines().ForEach( &lcl_CopyTblLine, &aPara ); +/*N*/ +/*N*/ if( pDDEType && pDoc->GetRootFrm() ) +/*?*/ pDDEType->IncRefCnt(); +/*N*/ +/*N*/ return pTblNd; +/*N*/ } + + + +// ----- Copy-Methode vom SwDoc ------ + + // verhinder das Kopieren in Fly's, die im Bereich verankert sind. + + + + + +// Kopieren eines Bereiches im oder in ein anderes Dokument ! + +/*N*/ BOOL SwDoc::Copy( SwPaM& rPam, SwPosition& rPos ) const +/*N*/ { +/*N*/ const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End(); +/*N*/ // kein Copy abfangen. +/*N*/ if( !rPam.HasMark() || *pStt >= *pEnd ) +/*N*/ return FALSE; +/*N*/ +/*N*/ SwDoc* pDoc = rPos.nNode.GetNode().GetDoc(); +/*N*/ +/*N*/ // verhinder das Kopieren in Fly's, die im Bereich verankert sind. +/*N*/ if( pDoc == this ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 // Start-/EndNode noch korrigieren +/*N*/ } +/*N*/ +/*N*/ SwPaM* pRedlineRange = 0; +/*N*/ if( pDoc->IsRedlineOn() || +/*N*/ (!pDoc->IsIgnoreRedline() && pDoc->GetRedlineTbl().Count() ) ) +/*N*/ pRedlineRange = new SwPaM( rPos ); +/*N*/ +/*N*/ SwRedlineMode eOld = pDoc->GetRedlineMode(); +/*N*/ +/*N*/ BOOL bRet = FALSE; +/*N*/ +/*N*/ if( pDoc && pDoc != this ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 bRet = _Copy( rPam, rPos, TRUE, pRedlineRange ); // nur normales Kopieren +/*N*/ // Copy in sich selbst (ueber mehrere Nodes wird hier gesondert +/*N*/ // behandelt; in einem TextNode wird normal behandelt) +/*N*/ else if( ! ( *pStt <= rPos && rPos < *pEnd && +/*N*/ ( pStt->nNode != pEnd->nNode || +/*N*/ !pStt->nNode.GetNode().IsTxtNode() )) ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 bRet = _Copy( rPam, rPos, TRUE, pRedlineRange ); // nur normales Kopieren +/*N*/ +/*N*/ else +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ASSERT( this == pDoc, " falscher Copy-Zweig!" ); +/*N*/ } +/*N*/ +/*N*/ pDoc->SetRedlineMode_intern( eOld ); +/*N*/ if( pRedlineRange ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( pDoc->IsRedlineOn() ) +/*N*/ } +/*N*/ +/*N*/ return bRet; +/*N*/ } + +// Kopieren eines Bereiches im oder in ein anderes Dokument ! +// Die Position darf nicht im Bereich liegen !! + + + +// ----- Copy-Methode vom SwDoc - "kopiere Fly's in Fly's" ------ + +/*N*/ void SwDoc::CopyWithFlyInFly( const SwNodeRange& rRg, +/*N*/ const SwNodeIndex& rInsPos, BOOL bMakeNewFrms, +/*N*/ BOOL bDelRedlines, BOOL bCopyFlyAtFly ) const +/*N*/ { +/*N*/ SwDoc* pDest = rInsPos.GetNode().GetDoc(); +/*N*/ +/*N*/ _SaveRedlEndPosForRestore aRedlRest( rInsPos ); +/*N*/ +/*N*/ SwNodeIndex aSavePos( rInsPos, -1 ); +/*N*/ BOOL bEndIsEqualEndPos = rInsPos == rRg.aEnd; +/*N*/ GetNodes()._CopyNodes( rRg, rInsPos, bMakeNewFrms, TRUE ); +/*N*/ aSavePos++; +/*N*/ if( bEndIsEqualEndPos ) +/*N*/ ((SwNodeIndex&)rRg.aEnd) = aSavePos; +/*N*/ +/*N*/ aRedlRest.Restore(); +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ { +/*N*/ //JP 17.06.99: Bug 66973 - check count only if the selection is in +/*N*/ // the same (or no) section. Becaus not full selected +/*N*/ // section are not copied. +/*N*/ const SwSectionNode* pSSectNd = rRg.aStart.GetNode().FindSectionNode(); +/*N*/ SwNodeIndex aTmpI( rRg.aEnd, -1 ); +/*N*/ const SwSectionNode* pESectNd = aTmpI.GetNode().FindSectionNode(); +/*N*/ if( pSSectNd == pESectNd && +/*N*/ !rRg.aStart.GetNode().IsSectionNode() && +/*N*/ !aTmpI.GetNode().IsEndNode() ) +/*N*/ { +/*N*/ ASSERT( rInsPos.GetIndex() - aSavePos.GetIndex() == +/*N*/ rRg.aEnd.GetIndex() - rRg.aStart.GetIndex(), +/*N*/ "Es wurden zu wenig Nodes kopiert!" ) +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ _CopyFlyInFly( rRg, aSavePos, bCopyFlyAtFly ); +/*N*/ +/*N*/ SwNodeRange aCpyRange( aSavePos, rInsPos ); +/*N*/ +/*N*/ // dann kopiere noch alle Bookmarks +/*N*/ if( GetBookmarks().Count() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwPaM aRgTmp( rRg.aStart, rRg.aEnd ); +/*N*/ } +/*N*/ +/*N*/ if( bDelRedlines && ( REDLINE_DELETE_REDLINES & pDest->GetRedlineMode() )) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 lcl_DeleteRedlines( rRg, aCpyRange ); +/*N*/ +/*N*/ pDest->GetNodes()._DelDummyNodes( aCpyRange ); +/*N*/ } + + +/*N*/ void SwDoc::_CopyFlyInFly( const SwNodeRange& rRg, const SwNodeIndex& rSttIdx, +/*N*/ BOOL bCopyFlyAtFly ) const +/*N*/ { +/*N*/ // Bug 22727: suche erst mal alle Flys zusammen, sortiere sie entsprechend +/*N*/ // ihrer Ordnungsnummer und kopiere sie erst dann. Damit wird +/*N*/ // die Ordnungsnummer (wird nur im DrawModel verwaltet) +/*N*/ // beibehalten. +/*N*/ SwDoc* pDest = rSttIdx.GetNode().GetDoc(); +/*N*/ _ZSortFlys aArr; +/*N*/ USHORT nArrLen = GetSpzFrmFmts()->Count(); + USHORT n=0; +/*N*/ for( n = 0; n < nArrLen; ++n ) +/*N*/ { +/*N*/ const SwFrmFmt* pFmt = (*GetSpzFrmFmts())[n]; +/*N*/ const SwFmtAnchor* pAnchor = &pFmt->GetAnchor(); +/*N*/ const SwPosition* pAPos; +/*N*/ if ( ( pAnchor->GetAnchorId() == FLY_AT_CNTNT || +/*N*/ pAnchor->GetAnchorId() == FLY_AT_FLY || +/*N*/ pAnchor->GetAnchorId() == FLY_AUTO_CNTNT ) && +/*N*/ 0 != ( pAPos = pAnchor->GetCntntAnchor()) && +/*N*/ (( bCopyFlyAtFly && FLY_AT_FLY == pAnchor->GetAnchorId() ) +/*N*/ ? rRg.aStart <= pAPos->nNode.GetIndex() + 1 +/*N*/ : ( IsRedlineMove() +/*N*/ ? rRg.aStart < pAPos->nNode +/*N*/ : rRg.aStart <= pAPos->nNode )) && +/*N*/ pAPos->nNode < rRg.aEnd ) +/*N*/ { +/*N*/ aArr.Insert( _ZSortFly( pFmt, pAnchor, nArrLen + aArr.Count() )); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Alle kopierten (also die neu erzeugten) Rahmen in ein weiteres Array +/*N*/ //stopfen. Dort sizten sie passend zu den Originalen, damit hinterher +/*N*/ //die Chains entsprechend aufgebaut werden koennen. +/*N*/ SvPtrarr aNewArr( 10, 10 ); +/*N*/ +/*N*/ for( n = 0; n < aArr.Count(); ++n ) +/*N*/ { +/*N*/ // neuen Anker anlegen +/*N*/ const _ZSortFly& rZSortFly = aArr[ n ]; +/*N*/ SwFmtAnchor aAnchor( *rZSortFly.GetAnchor() ); +/*N*/ SwPosition *pNewPos = (SwPosition*)aAnchor.GetCntntAnchor(); +/*N*/ long nOffset = pNewPos->nNode.GetIndex() - +/*N*/ rRg.aStart.GetIndex(); +/*N*/ SwNodeIndex aIdx( rSttIdx, nOffset ); +/*N*/ pNewPos->nNode = aIdx; +/*N*/ // die am Zeichen Flys wieder ans das vorgegebene Zeichen setzen +/*N*/ if( FLY_AUTO_CNTNT == aAnchor.GetAnchorId() && +/*N*/ aIdx.GetNode().IsTxtNode() ) +/*?*/ pNewPos->nContent.Assign( (SwTxtNode*)&aIdx.GetNode(), +/*?*/ pNewPos->nContent.GetIndex() ); +/*N*/ else +/*N*/ pNewPos->nContent.Assign( 0, 0 ); +/*N*/ +/*N*/ // ueberpruefe Rekursion: Inhalt in "seinen eigenen" Frame +/*N*/ // kopieren. Dann nicht kopieren +/*N*/ FASTBOOL bMakeCpy = TRUE; +/*N*/ if( pDest == this ) +/*N*/ { +/*N*/ const SwFmtCntnt& rCntnt = rZSortFly.GetFmt()->GetCntnt(); +/*N*/ const SwStartNode* pSNd; +/*N*/ if( rCntnt.GetCntntIdx() && +/*N*/ 0 != ( pSNd = rCntnt.GetCntntIdx()->GetNode().GetStartNode() ) && +/*N*/ pSNd->GetIndex() < rSttIdx.GetIndex() && +/*N*/ rSttIdx.GetIndex() < pSNd->EndOfSectionIndex() ) +/*N*/ { +/*?*/ bMakeCpy = FALSE; +/*?*/ aArr.Remove( n, 1 ); +/*?*/ --n; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Format kopieren und den neuen Anker setzen +/*N*/ if( bMakeCpy ) +/*N*/ aNewArr.Insert( pDest->CopyLayoutFmt( *rZSortFly.GetFmt(), +/*N*/ aAnchor, FALSE, TRUE/*FALSE*/ ), aNewArr.Count() ); +/*N*/ } +/*N*/ +/*N*/ //Alle chains, die im Original vorhanden sind, soweit wie moeglich wieder +/*N*/ //aufbauen. +/*N*/ ASSERT( aArr.Count() == aNewArr.Count(), "Missing new Flys" ); +/*N*/ if ( aArr.Count() == aNewArr.Count() ) +/*N*/ { +/*N*/ for ( n = 0; n < aArr.Count(); ++n ) +/*N*/ { +/*N*/ const SwFrmFmt *pFmt = aArr[n].GetFmt(); +/*N*/ const SwFmtChain &rChain = pFmt->GetChain(); +/*N*/ int nCnt = 0 != rChain.GetPrev(); +/*N*/ nCnt += rChain.GetNext() ? 1: 0; +/*N*/ for ( USHORT k = 0; nCnt && k < aArr.Count(); ++k ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 const _ZSortFly &rTmp = aArr[k]; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_ndindex.cxx b/binfilter/bf_sw/source/core/docnode/sw_ndindex.cxx new file mode 100644 index 000000000000..ebe69fa6235d --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_ndindex.cxx @@ -0,0 +1,156 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "errhdl.hxx" // fuers ASSERT +#include "error.h" // fuers ASSERT +#include "ndindex.hxx" +namespace binfilter { + +#ifdef DBG_UTIL +int SwNodeIndex::nSerial = 0; +#endif + + +/*N*/ SwNodeRange::SwNodeRange( const SwNodeIndex &rS, const SwNodeIndex &rE ) +/*N*/ : aStart( rS ), aEnd( rE ) +/*N*/ {} + +/*N*/ SwNodeRange::SwNodeRange( const SwNodeRange &rRange ) +/*N*/ : aStart( rRange.aStart ), aEnd( rRange.aEnd ) +/*N*/ {} + +/*N*/ SwNodeRange::SwNodeRange( const SwNodeIndex& rS, long nSttDiff, +/*N*/ const SwNodeIndex& rE, long nEndDiff ) +/*N*/ : aStart( rS, nSttDiff ), aEnd( rE, nEndDiff ) +/*N*/ {} + +/*N*/ SwNodeRange::SwNodeRange( const SwNode& rS, long nSttDiff, +/*N*/ const SwNode& rE, long nEndDiff ) +/*N*/ : aStart( rS, nSttDiff ), aEnd( rE, nEndDiff ) +/*N*/ {} + + +/*N*/ SwNodeIndex::SwNodeIndex( SwNodes& rNds, ULONG nIdx ) +/*N*/ : pNd( rNds[ nIdx ] ), pNext( 0 ), pPrev( 0 ) +/*N*/ { +/*N*/ rNds.RegisterIndex( *this ); +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ MySerial = ++nSerial; // nur in der nicht PRODUCT-Version +/*N*/ #endif +/*N*/ } + + +/*N*/ SwNodeIndex::SwNodeIndex( const SwNodeIndex& rIdx, long nDiff ) +/*N*/ : pNext( 0 ), pPrev( 0 ) +/*N*/ { +/*N*/ if( nDiff ) +/*N*/ pNd = rIdx.GetNodes()[ rIdx.GetIndex() + nDiff ]; +/*N*/ else +/*N*/ pNd = rIdx.pNd; +/*N*/ +/*N*/ pNd->GetNodes().RegisterIndex( *this ); +/*N*/ #ifdef DBG_UTIL +/*N*/ MySerial = ++nSerial; // nur in der nicht PRODUCT-Version +/*N*/ #endif +/*N*/ } + + +/*N*/ SwNodeIndex::SwNodeIndex( const SwNode& rNd, long nDiff ) +/*N*/ : pNext( 0 ), pPrev( 0 ) +/*N*/ { +/*N*/ if( nDiff ) +/*N*/ pNd = rNd.GetNodes()[ rNd.GetIndex() + nDiff ]; +/*N*/ else +/*N*/ pNd = (SwNode*)&rNd; +/*N*/ +/*N*/ pNd->GetNodes().RegisterIndex( *this ); +/*N*/ #ifdef DBG_UTIL +/*N*/ MySerial = ++nSerial; // nur in der nicht PRODUCT-Version +/*N*/ #endif +/*N*/ } + + +/*N*/ void SwNodeIndex::Remove() +/*N*/ { +/*N*/ pNd->GetNodes().DeRegisterIndex( *this ); +/*N*/ } + +/*N*/ SwNodeIndex& SwNodeIndex::operator=( const SwNodeIndex& rIdx ) +/*N*/ { +/*N*/ if( &pNd->GetNodes() != &rIdx.pNd->GetNodes() ) +/*N*/ { +/*N*/ pNd->GetNodes().DeRegisterIndex( *this ); +/*N*/ pNd = rIdx.pNd; +/*N*/ pNd->GetNodes().RegisterIndex( *this ); +/*N*/ } +/*N*/ else +/*N*/ pNd = rIdx.pNd; +/*N*/ return *this; +/*N*/ } + +/*N*/ SwNodeIndex& SwNodeIndex::operator=( const SwNode& rNd ) +/*N*/ { +/*N*/ if( &pNd->GetNodes() != &rNd.GetNodes() ) +/*N*/ { +/*?*/ pNd->GetNodes().DeRegisterIndex( *this ); +/*?*/ pNd = (SwNode*)&rNd; +/*?*/ pNd->GetNodes().RegisterIndex( *this ); +/*N*/ } +/*N*/ else +/*N*/ pNd = (SwNode*)&rNd; +/*N*/ return *this; +/*N*/ } + + +/*N*/ SwNodeIndex& SwNodeIndex::Assign( const SwNode& rNd, long nOffset ) +/*N*/ { +/*N*/ if( &pNd->GetNodes() != &rNd.GetNodes() ) +/*N*/ { +/*?*/ pNd->GetNodes().DeRegisterIndex( *this ); +/*?*/ pNd = (SwNode*)&rNd; +/*?*/ pNd->GetNodes().RegisterIndex( *this ); +/*N*/ } +/*N*/ else +/*N*/ pNd = (SwNode*)&rNd; +/*N*/ +/*N*/ if( nOffset ) +/*N*/ pNd = pNd->GetNodes()[ pNd->GetIndex() + nOffset ]; +/*N*/ +/*N*/ return *this; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_ndnotxt.cxx b/binfilter/bf_sw/source/core/docnode/sw_ndnotxt.cxx new file mode 100644 index 000000000000..051a34074fcf --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_ndnotxt.cxx @@ -0,0 +1,203 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif +#include <vcl/graph.hxx> +#include <vcl/gdimtf.hxx> +#include <bf_so3/ipobj.hxx> + +#include <tools/poly.hxx> +#include <vcl/outdev.hxx> + +#include <horiornt.hxx> + + +#include <errhdl.hxx> + +#include <ndgrf.hxx> +#include <ndole.hxx> +#include <hints.hxx> // fuer SwFmtChg +namespace binfilter { + + +/*N*/ SwNoTxtNode::SwNoTxtNode( const SwNodeIndex & rWhere, +/*N*/ const BYTE nNdType, +/*N*/ SwGrfFmtColl *pGrfColl, +/*N*/ SwAttrSet* pAutoAttr ) : +/*N*/ SwCntntNode( rWhere, nNdType, pGrfColl ), +/*N*/ pContour( 0 ), +/*N*/ bAutomaticContour( FALSE ), +/*N*/ bContourMapModeValid( TRUE ), +/*N*/ bPixelContour( FALSE ) +/*N*/ { +/*N*/ // soll eine Harte-Attributierung gesetzt werden? +/*N*/ if( pAutoAttr ) +/*N*/ SetAttr( *pAutoAttr ); +/*N*/ } + + +/*N*/ SwNoTxtNode::~SwNoTxtNode() +/*N*/ { +/*N*/ delete pContour; +/*N*/ } + + +// erzeugt fuer alle Ableitungen einen AttrSet mit Bereichen +// fuer Frame- und Grafik-Attributen +/*N*/ void SwNoTxtNode::NewAttrSet( SwAttrPool& rPool ) +/*N*/ { +/*N*/ ASSERT( !pAttrSet, "AttrSet ist doch gesetzt" ); +/*N*/ pAttrSet = new SwAttrSet( rPool, aNoTxtNodeSetRange ); +/*N*/ pAttrSet->SetParent( &GetFmtColl()->GetAttrSet() ); +/*N*/ } + +// Dummies fuer das Laden/Speichern von persistenten Daten +// bei Grafiken und OLE-Objekten + + + + + + +/*N*/ void SwNoTxtNode::SetContour( const PolyPolygon *pPoly, BOOL bAutomatic ) +/*N*/ { +/*N*/ delete pContour; +/*N*/ if ( pPoly ) +/*?*/ pContour = new PolyPolygon( *pPoly ); +/*N*/ else +/*N*/ pContour = 0; +/*N*/ bAutomaticContour = bAutomatic; +/*N*/ bContourMapModeValid = TRUE; +/*N*/ bPixelContour = FALSE; +/*N*/ } + + + +/*N*/ const PolyPolygon *SwNoTxtNode::HasContour() const +/*N*/ { +/*N*/ if( !bContourMapModeValid ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 const MapMode aGrfMap( GetGraphic().GetPrefMapMode() ); +/*N*/ } +/*N*/ +/*N*/ return pContour; +/*N*/ } + + + +/*N*/ BOOL SwNoTxtNode::GetContourAPI( PolyPolygon &rContour ) const +/*N*/ { +/*N*/ if( !pContour ) +/*N*/ return FALSE; +/*N*/ +/*?*/ rContour = *pContour; +/*?*/ if( bContourMapModeValid ) +/*?*/ { +/*?*/ const MapMode aGrfMap( GetGraphic().GetPrefMapMode() ); + /*?*/ const MapMode aContourMap( MAP_100TH_MM ); + /*?*/ ASSERT( aGrfMap.GetMapUnit() != MAP_PIXEL || + /*?*/ aGrfMap == MapMode( MAP_PIXEL ), + /*?*/ "scale factor for pixel unsupported" ); + /*?*/ if( aGrfMap.GetMapUnit() != MAP_PIXEL && + /*?*/ aGrfMap != aContourMap ) + /*?*/ { + /*?*/ USHORT nPolyCount = rContour.Count(); + /*?*/ for( USHORT j=0; j<nPolyCount; j++ ) + /*?*/ { + /*?*/ Polygon& rPoly = (*pContour)[j]; + /*?*/ + /*?*/ USHORT nCount = rPoly.GetSize(); + /*?*/ for( USHORT i=0 ; i<nCount; i++ ) + /*?*/ { + /*?*/ rPoly[i] = OutputDevice::LogicToLogic( rPoly[i], aGrfMap, + /*?*/ aContourMap ); + /*?*/ } + /*?*/ } + /*?*/ } +/*?*/ } +/*?*/ +/*?*/ return TRUE; +/*N*/ } + +BOOL SwNoTxtNode::IsPixelContour() const +{ + BOOL bRet; + if( bContourMapModeValid ) + { + const MapMode aGrfMap( GetGraphic().GetPrefMapMode() ); + bRet = aGrfMap.GetMapUnit() == MAP_PIXEL; + } + else + { + bRet = bPixelContour; + } + + return bRet; +} + + +Graphic SwNoTxtNode::GetGraphic() const +{ + Graphic aRet; + if ( GetGrfNode() ) + { + ((SwGrfNode*)this)->SwapIn( TRUE ); + aRet = ((SwGrfNode*)this)->GetGrf(); + } + else + { + ASSERT( GetOLENode(), "new type of Node?" ); + SvInPlaceObjectRef xObj( ((SwOLENode*)this)->GetOLEObj().GetOleRef() ); + GDIMetaFile aMtf; + aRet = xObj->GetGDIMetaFile( aMtf ); + } + return aRet; +} + + +/*N*/ void SwNoTxtNode::SetAlternateText( const String& rTxt, sal_Bool bBroadcast ) +/*N*/ { +/*N*/ if( bBroadcast ) +/*N*/ { +/*?*/ SwStringMsgPoolItem aOld( RES_ALT_TEXT_CHANGED, aAlternateText ); +/*?*/ SwStringMsgPoolItem aNew( RES_ALT_TEXT_CHANGED, rTxt ); +/*?*/ aAlternateText = rTxt; +/*?*/ Modify( &aOld, &aNew ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aAlternateText = rTxt; +/*N*/ } +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_ndnum.cxx b/binfilter/bf_sw/source/core/docnode/sw_ndnum.cxx new file mode 100644 index 000000000000..c293c178bfbf --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_ndnum.cxx @@ -0,0 +1,371 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <errhdl.hxx> + + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <ndtxt.hxx> +#include <fldbas.hxx> // UpdateFlds der KapitelNummerierung +namespace binfilter { + + +//------------------------------------------------------- +// Gliederung + +/*N*/ struct _OutlinePara +/*N*/ { +/*N*/ SwNodeNum aNum; +/*N*/ const SwNodes& rNds; +/*N*/ BYTE nMin, nNewLevel; +/*N*/ // OD 21.11.2002 #100043# - array to remember, which level numbering +/*N*/ // has to be started. +/*N*/ bool aStartLevel[ MAXLEVEL ]; +/*N*/ +/*N*/ _OutlinePara( const SwNodes& rNodes, USHORT nSttPos, BYTE nOld, BYTE nNew ); +/*N*/ BOOL UpdateOutline( SwTxtNode& rTxtNd ); +/*N*/ }; + +/*N*/ _SV_IMPL_SORTAR_ALG( SwOutlineNodes, SwNodePtr ) +/*N*/ BOOL SwOutlineNodes::Seek_Entry( const SwNodePtr rSrch, USHORT* pFndPos ) const +/*N*/ { +/*N*/ ULONG nIdx = rSrch->GetIndex(); +/*N*/ +/*N*/ register USHORT nO = Count(), nM, nU = 0; +/*N*/ if( nO > 0 ) +/*N*/ { +/*N*/ //JP 17.03.98: aufgrund des Bug 48592 - wo unter anderem nach Undo/Redo +/*N*/ // Nodes aus dem falschen NodesArray im OutlineArray standen, +/*N*/ // jetzt mal einen Check eingebaut. +/*N*/ #ifdef DBG_UTIL +/*N*/ { +/*N*/ for( register USHORT n = 1; n < nO; ++n ) +/*N*/ if( &(*this)[ n-1 ]->GetNodes() != +/*N*/ &(*this)[ n ]->GetNodes() ) +/*N*/ { +/*?*/ ASSERT( !this, "Node im falschen Outline-Array" ); +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ nO--; +/*N*/ while( nU <= nO ) +/*N*/ { +/*N*/ nM = nU + ( nO - nU ) / 2; +/*N*/ if( (*this)[ nM ] == rSrch ) +/*N*/ { +/*N*/ if( pFndPos ) +/*N*/ *pFndPos = nM; +/*N*/ return TRUE; +/*N*/ } +/*N*/ else if( (*this)[ nM ]->GetIndex() < nIdx ) +/*N*/ nU = nM + 1; +/*N*/ else if( nM == 0 ) +/*N*/ { +/*N*/ if( pFndPos ) +/*N*/ *pFndPos = nU; +/*N*/ return FALSE; +/*N*/ } +/*N*/ else +/*N*/ nO = nM - 1; +/*N*/ } +/*N*/ } +/*N*/ if( pFndPos ) +/*N*/ *pFndPos = nU; +/*N*/ return FALSE; +/*N*/ } + + +/*N*/ _OutlinePara::_OutlinePara( const SwNodes& rNodes, USHORT nSttPos, +/*N*/ BYTE nOld, BYTE nNew ) +/*N*/ : rNds( rNodes ), +/*N*/ aNum( NO_NUM > nNew ? nNew : 0 ), +/*N*/ nMin( Min( nOld, nNew )), +/*N*/ nNewLevel( nNew ) +/*N*/ { +/*N*/ // OD 25.11.2002 #100043# - init <aStartLevel[]> with defaults, only valid +/*N*/ // if update of outline numbering started at first outline numbering node. +/*N*/ for ( int i = 0; i < MAXLEVEL; ++i) +/*N*/ aStartLevel[i] = true; +/*N*/ +/*N*/ // hole vom Vorgaenger die aktuelle Nummerierung +/*N*/ SwNode* pNd; +/*N*/ ULONG nEndOfExtras = rNds.GetEndOfExtras().GetIndex(); +/*N*/ if ( nSttPos && +/*N*/ (pNd = rNds.GetOutLineNds()[ --nSttPos ])->GetIndex() > nEndOfExtras && +/*N*/ static_cast<SwTxtNode*>(pNd)->GetOutlineNum() +/*N*/ ) +/*N*/ { +/*N*/ const SwNodeNum* pNum = ((SwTxtNode*)pNd)->GetOutlineNum(); +/*N*/ #ifdef TASK_59308 +/*N*/ if( pNum->GetLevel() & NO_NUMLEVEL ) +/*N*/ { +/*N*/ // dann suche den mit richtigem Level: +/*N*/ BYTE nSrchLvl = aNum.GetLevel(); +/*N*/ pNum = 0; +/*N*/ while( nSttPos-- ) +/*N*/ { +/*N*/ if( ( pNd = rNds.GetOutLineNds()[ nSttPos ])-> +/*N*/ GetIndex() < nEndOfExtras ) +/*N*/ break; +/*N*/ +/*N*/ if( 0 != ( pNum = ((SwTxtNode*)pNd)->GetOutlineNum() )) +/*N*/ { +/*N*/ // uebergeordnete Ebene +/*N*/ if( nSrchLvl > (pNum->GetLevel() &~ NO_NUMLEVEL )) +/*N*/ { +/*N*/ pNum = 0; +/*N*/ break; +/*N*/ } +/*N*/ // gleiche Ebene und kein NO_NUMLEVEL +/*N*/ if( nSrchLvl == (pNum->GetLevel() &~ NO_NUMLEVEL) +/*N*/ && !( pNum->GetLevel() & NO_NUMLEVEL )) +/*N*/ break; +/*N*/ +/*N*/ pNum = 0; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ #endif +/*N*/ if( pNum ) +/*N*/ { +/*N*/ aNum = *pNum; +/*N*/ aNum.SetStart( FALSE ); +/*N*/ aNum.SetSetValue( USHRT_MAX ); +/*N*/ } +/*N*/ +/*N*/ if( aNum.GetLevel()+1 < MAXLEVEL ) +/*N*/ { +/*N*/ memset( aNum.GetLevelVal() + (aNum.GetLevel()+1), 0, +/*N*/ (MAXLEVEL - (aNum.GetLevel()+1)) * sizeof(aNum.GetLevelVal()[0]) ); +/*N*/ } +/*N*/ // OD 22.11.2002 #100043# - init array <aStartLevel[]>, not starting at +/*N*/ // first outline numbering node. +/*N*/ aStartLevel[ pNum->GetLevel() ] = false; +/*N*/ USHORT nHighestLevelFound = pNum->GetLevel(); +/*N*/ while ( pNum->GetLevel() > 0 && nSttPos-- ) +/*N*/ { +/*N*/ pNd = rNds.GetOutLineNds()[ nSttPos ]; +/*N*/ if ( pNd->GetIndex() < nEndOfExtras ) +/*N*/ break; +/*N*/ pNum = static_cast<SwTxtNode*>(pNd)->GetOutlineNum(); +/*N*/ if ( pNum && pNum->GetLevel() < nHighestLevelFound ) +/*N*/ { +/*N*/ aStartLevel[ pNum->GetLevel() ] = false; +/*N*/ nHighestLevelFound = pNum->GetLevel(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ BOOL _OutlinePara::UpdateOutline( SwTxtNode& rTxtNd ) +/*N*/ { +/*N*/ // alle die ausserhalb des Fliesstextes liegen, NO_NUM zuweisen. +/*N*/ if( rTxtNd.GetIndex() < rNds.GetEndOfExtras().GetIndex() ) +/*N*/ { +/*N*/ BYTE nTmpLevel = aNum.GetLevel(); +/*N*/ aNum.SetLevel( NO_NUM ); +/*N*/ rTxtNd.UpdateOutlineNum( aNum ); +/*N*/ aNum.SetLevel( nTmpLevel ); +/*N*/ return TRUE; +/*N*/ } +/*N*/ +/*N*/ BYTE nLevel = rTxtNd.GetTxtColl()->GetOutlineLevel(); +/*N*/ BOOL bRet = !(nMin > nLevel); +/*N*/ if( bRet ) +/*N*/ { +/*N*/ // existierte am Node schon eine Nummerierung ?? +/*N*/ // dann erfrage den "User definierten Wert" +/*N*/ USHORT nSetValue; +/*N*/ const SwNumRule* pOutlRule = rTxtNd.GetDoc()->GetOutlineNumRule(); +/*N*/ const SwNodeNum* pOutlNum = rTxtNd.GetOutlineNum(); +/*N*/ +/*N*/ #ifdef TASK_59308 +/*N*/ if( pOutlNum && ( pOutlNum->GetLevel() & NO_NUMLEVEL ) && +/*N*/ GetRealLevel( pOutlNum->GetLevel() ) == nLevel ) +/*N*/ { +/*N*/ // diesen nicht mit numerieren +/*N*/ BYTE nTmpLevel = aNum.GetLevel(); +/*N*/ aNum.SetLevel( pOutlNum->GetLevel() ); +/*N*/ rTxtNd.UpdateOutlineNum( aNum ); +/*N*/ aNum.SetLevel( nTmpLevel ); +/*N*/ return TRUE; +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ // OD 21.11.2002 #100043# - determine, if level numbering has to be started. +/*N*/ // OD 09.12.2002 #106070# - correct outline numbering, even for the +/*N*/ // first heading. Thus, state of <aStartLevel[]> always has to be +/*N*/ // consulted, not only on level change. +/*N*/ if( aStartLevel[ nLevel ] ) +/*N*/ { +/*N*/ nSetValue= pOutlRule->Get( nLevel ).GetStart(); +/*N*/ // OD 21.11.2002 #100043# - reset <aStartLevel[nLevel]> +/*N*/ aStartLevel[ nLevel ] = false; +/*N*/ } +/*N*/ else +/*N*/ nSetValue = aNum.GetLevelVal()[ nLevel ] + 1; +/*N*/ +/*N*/ // alle unter dem neuen Level liegenden auf 0 setzen +/*N*/ if( aNum.GetLevel() > nLevel && nLevel+1 < MAXLEVEL +/*N*/ /* ??? && NO_NUM > nNewLevel */ ) +/*N*/ { +/*N*/ memset( aNum.GetLevelVal() + (nLevel+1), 0, +/*N*/ (MAXLEVEL - ( nLevel+1 )) * sizeof(aNum.GetLevelVal()[0]) ); +/*N*/ // OD 22.11.2002 #100043# - all next level numberings have to be started. +/*N*/ for ( int i = nLevel+1; i < MAXLEVEL; ++i) +/*N*/ aStartLevel[i] = true; +/*N*/ } +/*N*/ +/*N*/ if( pOutlNum && USHRT_MAX != pOutlNum->GetSetValue() ) +/*N*/ aNum.SetSetValue( nSetValue = pOutlNum->GetSetValue() ); +/*N*/ +/*N*/ aNum.GetLevelVal()[ nLevel ] = nSetValue; +/*N*/ aNum.SetLevel( nLevel ); +/*N*/ rTxtNd.UpdateOutlineNum( aNum ); +/*N*/ aNum.SetSetValue( USHRT_MAX ); +/*N*/ } +/*N*/ return bRet; +/*N*/ } + + + + +/*N*/ BOOL lcl_UpdateOutline( const SwNodePtr& rpNd, void* pPara ) +/*N*/ { +/*N*/ _OutlinePara* pOutlPara = (_OutlinePara*)pPara; +/*N*/ SwTxtNode* pTxtNd = rpNd->GetTxtNode(); +/*N*/ ASSERT( pTxtNd, "kein TextNode als OutlineNode !" ); +/*N*/ +/*N*/ return pOutlPara->UpdateOutline( *pTxtNd ); +/*N*/ } + + + + +/*N*/ void SwNodes::UpdateOutlineNode( const SwNode& rNd, BYTE nOldLevel, +/*N*/ BYTE nNewLevel ) +/*N*/ { +/*N*/ const SwNodePtr pSrch = (SwNodePtr)&rNd; +/*N*/ USHORT nSttPos; +/*N*/ BOOL bSeekIdx = pOutlineNds->Seek_Entry( pSrch, &nSttPos ); +/*N*/ +/*N*/ if( NO_NUMBERING == nOldLevel ) // neuen Level einfuegen +/*N*/ { +/*N*/ // nicht vorhanden, also einfuegen +/*N*/ ASSERT( !bSeekIdx, "Der Node ist schon als OutlineNode vorhanden" ); +/*N*/ +/*N*/ //JP 12.03.99: 63293 - Nodes vom RedlineBereich NIE aufnehmen +/*N*/ ULONG nNd = rNd.GetIndex(); +/*N*/ if( nNd < GetEndOfRedlines().GetIndex() && +/*N*/ nNd > GetEndOfRedlines().FindStartNode()->GetIndex() ) +/*?*/ return ; +/*N*/ +/*N*/ // jetzt noch alle nachfolgende Outline-Nodes updaten +/*N*/ pOutlineNds->Insert( pSrch ); +/*N*/ if( NO_NUM <= nNewLevel ) +/*?*/ return; // keine Nummerierung dann kein Update +/*N*/ } +/*N*/ else if( NO_NUMBERING == nNewLevel ) // Level entfernen +/*N*/ { +/*?*/ if( !bSeekIdx ) +/*?*/ return; +/*?*/ +/*?*/ // jetzt noch alle nachfolgende Outline-Nodes updaten +/*?*/ pOutlineNds->Remove( nSttPos ); +/*?*/ if( NO_NUM <= nOldLevel ) +/*?*/ return; // keine Nummerierung dann kein Update +/*N*/ } +/*N*/ else if( !bSeekIdx ) // Update und Index nicht gefunden ?? +/*?*/ return ; +/*N*/ +/*N*/ _OutlinePara aPara( *this, nSttPos, nOldLevel, nNewLevel ); +/*N*/ pOutlineNds->ForEach( nSttPos, pOutlineNds->Count(), +/*N*/ lcl_UpdateOutline, &aPara ); +/*N*/ +/*N*/ //FEATURE::CONDCOLL +/*N*/ { +/*N*/ SwCntntNode* pCNd; +/*N*/ ULONG nSttNd = rNd.GetIndex(); +/*N*/ if( NO_NUMBERING != nNewLevel ) +/*N*/ ++nSttPos; +/*N*/ +/*N*/ ULONG nChkCount = ( nSttPos < pOutlineNds->Count() +/*N*/ ? (*pOutlineNds)[ nSttPos ]->GetIndex() +/*N*/ : GetEndOfContent().GetIndex() ) +/*N*/ - nSttNd; +/*N*/ for( ; nChkCount--; ++nSttNd ) +/*N*/ if( 0 != (pCNd = (*this)[ nSttNd ]->GetCntntNode() ) && +/*N*/ RES_CONDTXTFMTCOLL == pCNd->GetFmtColl()->Which() ) +/*N*/ pCNd->ChkCondColl(); +/*N*/ } +/*N*/ //FEATURE::CONDCOLL +/*N*/ +/*N*/ // die Gliederungs-Felder Updaten +/*N*/ GetDoc()->GetSysFldType( RES_CHAPTERFLD )->UpdateFlds(); +/*N*/ } + + + +/*N*/ void SwNodes::UpdtOutlineIdx( const SwNode& rNd ) +/*N*/ { +/*N*/ if( !pOutlineNds->Count() ) // keine OutlineNodes vorhanden ? +/*N*/ return; +/*N*/ +/*N*/ const SwNodePtr pSrch = (SwNodePtr)&rNd; +/*N*/ USHORT nPos; +/*N*/ pOutlineNds->Seek_Entry( pSrch, &nPos ); +/*N*/ if( nPos == pOutlineNds->Count() ) // keine zum Updaten vorhanden ? +/*N*/ return; +/*N*/ +/*N*/ if( nPos ) +/*N*/ --nPos; +/*N*/ +/*N*/ if( !GetDoc()->IsInDtor() && IsDocNodes() ) +/*N*/ UpdateOutlineNode( *(*pOutlineNds)[ nPos ], 0, 0 ); +/*N*/ } + + + +/*N*/ void SwNodes::UpdateOutlineNodes() +/*N*/ { +/*N*/ if( pOutlineNds->Count() ) // OutlineNodes vorhanden ? +/*N*/ UpdateOutlineNode( *(*pOutlineNds)[ 0 ], 0, 0 ); +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_ndsect.cxx b/binfilter/bf_sw/source/core/docnode/sw_ndsect.cxx new file mode 100644 index 000000000000..2dcdeb6a4413 --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_ndsect.cxx @@ -0,0 +1,940 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <bf_svx/linkmgr.hxx> +#include <bf_svtools/itemiter.hxx> +#include <tools/resid.hxx> + +#include <fmtcntnt.hxx> +#include <txtftn.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <rootfrm.hxx> +#include <ndtxt.hxx> +#include <swtable.hxx> +#include <ftnidx.hxx> +#include <docary.hxx> +#include <redline.hxx> +#include <sectfrm.hxx> +#include <cntfrm.hxx> +#include <node2lay.hxx> +#include <doctxm.hxx> +#include <fmtftntx.hxx> +#include <hints.hxx> + +#include <comcore.hrc> +namespace binfilter { + +/*N*/ int lcl_IsInSameTblBox( SwNodes& rNds, const SwNode& rNd, +/*N*/ const SwNodeIndex& rIdx2 ) +/*N*/ { +/*N*/ const SwTableNode* pTblNd = rNd.FindTableNode(); +/*N*/ if( !pTblNd ) +/*N*/ return TRUE; +/*N*/ +/*?*/ // dann suche den StartNode der Box +/*?*/ const SwTableSortBoxes& rSortBoxes = pTblNd->GetTable().GetTabSortBoxes(); +/*?*/ ULONG nIdx = rNd.GetIndex(); +/*?*/ for( USHORT n = 0; n < rSortBoxes.Count(); ++n ) +/*?*/ { +/*?*/ const SwStartNode* pNd = rSortBoxes[ n ]->GetSttNd(); +/*?*/ if( pNd->GetIndex() < nIdx && +/*?*/ nIdx < pNd->EndOfSectionIndex() ) +/*?*/ { +/*?*/ // dann muss der andere Index in derselben Section liegen +/*?*/ nIdx = rIdx2.GetIndex(); +/*?*/ return pNd->GetIndex() < nIdx && nIdx < pNd->EndOfSectionIndex(); +/*?*/ } +/*?*/ } +/*?*/ return TRUE; +/*N*/ } + + +/*N*/ SwSection* SwDoc::Insert( const SwPaM& rRange, const SwSection& rNew, +/*N*/ const SfxItemSet* pAttr, BOOL bUpdate ) +/*N*/ { +/*N*/ const SwNode* pPrvNd = 0; +/*N*/ USHORT nRegionRet = 0; +/*N*/ if( rRange.HasMark() && +/*N*/ 0 == ( nRegionRet = IsInsRegionAvailable( rRange, &pPrvNd ) )) +/*N*/ { +/*?*/ ASSERT( !this, "Selection ueber verschiedene Sections" ); +/*?*/ return 0; +/*N*/ } +/*N*/ +/*N*/ // Teste ob das gesamte Dokument versteckt werden soll, +/*N*/ // koennen wir zur Zeit nicht !!!! +/*N*/ if( rNew.IsHidden() && rRange.HasMark() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 const SwPosition *pStt = rRange.Start(), *pEnd = rRange.End(); +/*N*/ } +/*N*/ +/*N*/ SwSectionFmt* pFmt = MakeSectionFmt( 0 ); +/*N*/ if( pAttr ) +/*N*/ pFmt->SetAttr( *pAttr ); +/*N*/ +/*N*/ SwSectionNode* pNewSectNode = 0; +/*N*/ +/*N*/ SwRedlineMode eOld = GetRedlineMode(); +/*N*/ SetRedlineMode_intern( (eOld & ~REDLINE_SHOW_MASK) | REDLINE_IGNORE ); +/*N*/ +/*N*/ if( rRange.HasMark() ) +/*N*/ { +/*N*/ SwPosition *pSttPos = (SwPosition*)rRange.Start(), +/*N*/ *pEndPos = (SwPosition*)rRange.End(); +/*N*/ if( pPrvNd && 3 == nRegionRet ) +/*N*/ { +/*?*/ ASSERT( pPrvNd, "der SectionNode fehlt" ); +/*?*/ SwNodeIndex aStt( pSttPos->nNode ), aEnd( pEndPos->nNode, +1 ); +/*?*/ while( pPrvNd != aStt.GetNode().FindStartNode() ) +/*?*/ aStt--; +/*?*/ while( pPrvNd != aEnd.GetNode().FindStartNode() ) +/*?*/ aEnd++; +/*?*/ +/*?*/ --aEnd; // im InsertSection ist Ende inclusive +/*?*/ pNewSectNode = GetNodes().InsertSection( aStt, *pFmt, rNew, &aEnd ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const SwCntntNode* pCNd; +/*N*/ if( pPrvNd && 1 == nRegionRet ) +/*N*/ { +/*?*/ pSttPos->nNode.Assign( *pPrvNd ); +/*?*/ pSttPos->nContent.Assign( pSttPos->nNode.GetNode().GetCntntNode(), 0 ); +/*N*/ } +/*N*/ else if( pSttPos->nContent.GetIndex() ) +/*?*/ SplitNode( *pSttPos ); +/*N*/ +/*N*/ if( pPrvNd && 2 == nRegionRet ) +/*N*/ { +/*?*/ pEndPos->nNode.Assign( *pPrvNd ); +/*?*/ pEndPos->nContent.Assign( pEndPos->nNode.GetNode().GetCntntNode(), 0 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pCNd = pEndPos->nNode.GetNode().GetCntntNode(); +/*N*/ if( pCNd && pCNd->Len() != pEndPos->nContent.GetIndex() ) +/*N*/ { +/*?*/ xub_StrLen nCntnt = pSttPos->nContent.GetIndex(); +/*?*/ SplitNode( *pEndPos ); +/*?*/ +/*?*/ SwTxtNode* pTNd; +/*?*/ if( pEndPos->nNode.GetIndex() == pSttPos->nNode.GetIndex() ) +/*?*/ { +/*?*/ pSttPos->nNode--; +/*?*/ pEndPos->nNode--; +/*?*/ pTNd = pSttPos->nNode.GetNode().GetTxtNode(); +/*?*/ pSttPos->nContent.Assign( pTNd, nCntnt ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ // wieder ans Ende vom vorherigen setzen +/*?*/ pEndPos->nNode--; +/*?*/ pTNd = pEndPos->nNode.GetNode().GetTxtNode(); +/*?*/ } +/*?*/ if( pTNd ) nCntnt = pTNd->GetTxt().Len(); else nCntnt = 0; +/*?*/ pEndPos->nContent.Assign( pTNd, nCntnt ); +/*N*/ } +/*N*/ } +/*N*/ pNewSectNode = GetNodes().InsertSection( pSttPos->nNode, *pFmt, rNew, +/*N*/ &pEndPos->nNode ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const SwPosition* pPos = rRange.GetPoint(); +/*N*/ const SwCntntNode* pCNd = pPos->nNode.GetNode().GetCntntNode(); +/*N*/ if( !pPos->nContent.GetIndex() ) +/*N*/ { +/*N*/ pNewSectNode = GetNodes().InsertSection( pPos->nNode, *pFmt, rNew, 0, TRUE ); +/*N*/ } +/*N*/ else if( pPos->nContent.GetIndex() == pCNd->Len() ) +/*N*/ { +/*?*/ pNewSectNode = GetNodes().InsertSection( pPos->nNode, *pFmt, rNew, 0, FALSE ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ SplitNode( *pPos ); +/*?*/ pNewSectNode = GetNodes().InsertSection( pPos->nNode, *pFmt, rNew, 0, TRUE ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //FEATURE::CONDCOLL +/*N*/ pNewSectNode->CheckSectionCondColl(); +/*N*/ //FEATURE::CONDCOLL +/*N*/ +/*N*/ SetRedlineMode_intern( eOld ); +/*N*/ +/*N*/ if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwPaM aPam( *pNewSectNode->EndOfSectionNode(), *pNewSectNode, 1 ); +/*N*/ } +/*N*/ +/*N*/ // ist eine Condition gesetzt +/*N*/ if( rNew.IsHidden() && rNew.GetCondition().Len() ) +/*N*/ { +/*?*/ // dann berechne bis zu dieser Position +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwCalc aCalc( *this ); +/*N*/ } +/*N*/ +/*N*/ BOOL bUpdateFtn = FALSE; +/*N*/ if( GetFtnIdxs().Count() && pAttr ) +/*N*/ { +/*?*/ USHORT nVal = ((SwFmtFtnAtTxtEnd&)pAttr->Get( +/*?*/ RES_FTN_AT_TXTEND )).GetValue(); +/*?*/ if( ( FTNEND_ATTXTEND_OWNNUMSEQ == nVal || +/*?*/ FTNEND_ATTXTEND_OWNNUMANDFMT == nVal ) || +/*?*/ ( FTNEND_ATTXTEND_OWNNUMSEQ == ( nVal = ((SwFmtEndAtTxtEnd&) +/*?*/ pAttr->Get( RES_END_AT_TXTEND )).GetValue() ) || +/*?*/ FTNEND_ATTXTEND_OWNNUMANDFMT == nVal )) +/*?*/ bUpdateFtn = TRUE; +/*N*/ } +/*N*/ +/*N*/ if( rNew.IsLinkType() ) +/*?*/ pNewSectNode->GetSection().CreateLink( bUpdate ? CREATE_UPDATE : CREATE_CONNECT ); +/*N*/ +/*N*/ if( bUpdateFtn ) +/*?*/ GetFtnIdxs().UpdateFtn( SwNodeIndex( *pNewSectNode )); +/*N*/ +/*N*/ SetModified(); +/*N*/ return &pNewSectNode->GetSection(); +/*N*/ } + +/*N*/ USHORT SwDoc::IsInsRegionAvailable( const SwPaM& rRange, +/*N*/ const SwNode** ppSttNd ) const +/*N*/ { +/*N*/ USHORT nRet = 1; +/*N*/ if( rRange.HasMark() ) +/*N*/ { +/*N*/ // teste ob es sich um eine gueltige Selektion handelt +/*N*/ const SwPosition* pStt = rRange.Start(), +/*N*/ * pEnd = rRange.End(); +/*N*/ +/*N*/ const SwCntntNode* pCNd = pEnd->nNode.GetNode().GetCntntNode(); +/*N*/ const SwNode* pNd = &pStt->nNode.GetNode(); +/*N*/ const SwSectionNode* pSectNd = pNd->FindSectionNode(); +/*N*/ const SwSectionNode* pEndSectNd = pCNd ? pCNd->FindSectionNode() : 0; +/*N*/ if( pSectNd && pEndSectNd && pSectNd != pEndSectNd ) +/*N*/ { +/*?*/ // versuche eine umschliessende Section zu erzeugen +/*?*/ // Aber, nur wenn der Start am Sectionanfang und das Ende am +/*?*/ // Section Ende liegt! +/*?*/ nRet = 0; +/*?*/ if( !pStt->nContent.GetIndex() && pSectNd->GetIndex() +/*?*/ == pStt->nNode.GetIndex() - 1 && pEnd->nContent.GetIndex() == +/*?*/ pCNd->Len() ) +/*?*/ { +/*?*/ SwNodeIndex aIdx( pStt->nNode, -1 ); +/*?*/ ULONG nCmp = pEnd->nNode.GetIndex(); +/*?*/ const SwStartNode* pPrvNd; +/*?*/ const SwEndNode* pNxtNd; +/*?*/ while( 0 != ( pPrvNd = (pNd = &aIdx.GetNode())->GetSectionNode() ) && +/*?*/ !( aIdx.GetIndex() < nCmp && +/*?*/ nCmp < pPrvNd->EndOfSectionIndex() ) ) +/*?*/ { +/*?*/ aIdx--; +/*?*/ } +/*?*/ if( !pPrvNd ) +/*?*/ pPrvNd = pNd->IsStartNode() ? (SwStartNode*)pNd +/*?*/ : pNd->FindStartNode(); +/*?*/ +/*?*/ aIdx = pEnd->nNode.GetIndex() + 1; +/*?*/ nCmp = pStt->nNode.GetIndex(); +/*?*/ while( 0 != ( pNxtNd = (pNd = &aIdx.GetNode())->GetEndNode() ) && +/*?*/ pNxtNd->FindStartNode()->IsSectionNode() && +/*?*/ !( pNxtNd->StartOfSectionIndex() < nCmp && +/*?*/ nCmp < aIdx.GetIndex() ) ) +/*?*/ { +/*?*/ aIdx++; +/*?*/ } +/*?*/ if( !pNxtNd ) +/*?*/ pNxtNd = pNd->EndOfSectionNode(); +/*?*/ +/*?*/ if( pPrvNd && pNxtNd && pPrvNd == pNxtNd->FindStartNode() ) +/*?*/ { +/*?*/ nRet = 3; +/*?*/ +/*?*/ if( ppSttNd ) +/*?*/ *ppSttNd = pPrvNd; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ else if( !pSectNd && pEndSectNd ) +/*N*/ { +/*?*/ // versuche eine umschliessende Section zu erzeugen +/*?*/ // Aber, nur wenn das Ende am Section Ende liegt! +/*?*/ nRet = 0; +/*?*/ if( pEnd->nContent.GetIndex() == pCNd->Len() ) +/*?*/ { +/*?*/ SwNodeIndex aIdx( pEnd->nNode, 1 ); +/*?*/ if( aIdx.GetNode().IsEndNode() && +/*?*/ 0 != aIdx.GetNode().FindSectionNode() ) +/*?*/ { +/*?*/ do { +/*?*/ aIdx++; +/*?*/ } while( aIdx.GetNode().IsEndNode() && +/*?*/ 0 != aIdx.GetNode().FindSectionNode() ); +/*?*/ // if( !aIdx.GetNode().IsEndNode() ) +/*?*/ { +/*?*/ nRet = 2; +/*?*/ if( ppSttNd ) +/*?*/ { +/*?*/ aIdx--; +/*?*/ *ppSttNd = &aIdx.GetNode(); +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ else if( pSectNd && !pEndSectNd ) +/*N*/ { +/*?*/ // versuche eine umschliessende Section zu erzeugen +/*?*/ // Aber, nur wenn der Start am Section Anfang liegt! +/*?*/ nRet = 0; +/*?*/ if( !pStt->nContent.GetIndex() ) +/*?*/ { +/*?*/ SwNodeIndex aIdx( pStt->nNode, -1 ); +/*?*/ if( aIdx.GetNode().IsSectionNode() ) +/*?*/ { +/*?*/ do { +/*?*/ aIdx--; +/*?*/ } while( aIdx.GetNode().IsSectionNode() ); +/*?*/ if( !aIdx.GetNode().IsSectionNode() ) +/*?*/ { +/*?*/ nRet = 1; +/*?*/ if( ppSttNd ) +/*?*/ { +/*?*/ aIdx++; +/*?*/ *ppSttNd = &aIdx.GetNode(); +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/*N*/ SwSection* SwDoc::GetCurrSection( const SwPosition& rPos ) const +/*N*/ { +/*N*/ const SwSectionNode* pSectNd = rPos.nNode.GetNode().FindSectionNode(); +/*N*/ if( pSectNd ) +/*N*/ return (SwSection*)&pSectNd->GetSection(); +/*N*/ return 0; +/*N*/ } + +/*N*/ SwSectionFmt* SwDoc::MakeSectionFmt( SwSectionFmt *pDerivedFrom ) +/*N*/ { +/*N*/ if( !pDerivedFrom ) +/*N*/ pDerivedFrom = (SwSectionFmt*)pDfltFrmFmt; +/*N*/ SwSectionFmt* pNew = new SwSectionFmt( pDerivedFrom, this ); +/*N*/ pSectionFmtTbl->Insert( pNew, pSectionFmtTbl->Count() ); +/*N*/ return pNew; +/*N*/ } + +/*N*/ void SwDoc::DelSectionFmt( SwSectionFmt *pFmt, BOOL bDelNodes ) +/*N*/ { +/*N*/ USHORT nPos = pSectionFmtTbl->GetPos( pFmt ); +/*N*/ if( USHRT_MAX != nPos ) +/*N*/ { +/*N*/ const SwNodeIndex* pIdx = pFmt->GetCntnt( FALSE ).GetCntntIdx(); +/*N*/ const SfxPoolItem* pFtnEndAtTxtEnd; +/*N*/ if( SFX_ITEM_SET != pFmt->GetItemState( +/*N*/ RES_FTN_AT_TXTEND, TRUE, &pFtnEndAtTxtEnd ) || +/*N*/ SFX_ITEM_SET != pFmt->GetItemState( +/*N*/ RES_END_AT_TXTEND, TRUE, &pFtnEndAtTxtEnd )) +/*N*/ pFtnEndAtTxtEnd = 0; +/*N*/ +/*N*/ const SwSectionNode* pSectNd; +/*N*/ +/*N*/ if( bDelNodes && pIdx && &GetNodes() == &pIdx->GetNodes() && +/*N*/ 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) +/*N*/ { +/*?*/ SwNodeIndex aUpdIdx( *pIdx ); +/*?*/ DeleteSection( (SwNode*)pSectNd ); +/*?*/ if( pFtnEndAtTxtEnd ) +/*?*/ GetFtnIdxs().UpdateFtn( aUpdIdx ); +/*?*/ SetModified(); +/*?*/ return ; +/*N*/ } +/*N*/ +/*N*/ { +/*N*/ SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFmt ); +/*N*/ pFmt->Modify( &aMsgHint, &aMsgHint ); +/*N*/ } +/*N*/ +/*N*/ // ACHTUNG: erst aus dem Array entfernen und dann loeschen. +/*N*/ // Der Section-DTOR versucht selbst noch sein Format +/*N*/ // zu loeschen! +/*N*/ pSectionFmtTbl->Remove( nPos ); +/*N*/ //FEATURE::CONDCOLL +/*N*/ ULONG nCnt = 0, nSttNd = 0; +/*N*/ if( pIdx && &GetNodes() == &pIdx->GetNodes() && +/*N*/ 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) +/*N*/ { +/*?*/ nSttNd = pSectNd->GetIndex(); +/*?*/ nCnt = pSectNd->EndOfSectionIndex() - nSttNd - 1; +/*N*/ } +/*N*/ //FEATURE::CONDCOLL +/*N*/ +/*N*/ delete pFmt; +/*N*/ +/*N*/ if( nSttNd && pFtnEndAtTxtEnd ) +/*N*/ { +/*?*/ SwNodeIndex aUpdIdx( GetNodes(), nSttNd ); +/*?*/ GetFtnIdxs().UpdateFtn( aUpdIdx ); +/*N*/ } +/*N*/ +/*N*/ //FEATURE::CONDCOLL +/*N*/ SwCntntNode* pCNd; +/*N*/ for( ; nCnt--; ++nSttNd ) +/*N*/ if( 0 != (pCNd = GetNodes()[ nSttNd ]->GetCntntNode() ) && +/*?*/ RES_CONDTXTFMTCOLL == pCNd->GetFmtColl()->Which() ) +/*?*/ pCNd->ChkCondColl(); +/*N*/ //FEATURE::CONDCOLL +/*N*/ } +/*N*/ SetModified(); +/*N*/ } + +/*N*/ void SwDoc::ChgSection( USHORT nPos, const SwSection& rSect, +/*N*/ const SfxItemSet* pAttr, +/*N*/ sal_Bool bPreventLinkUpdate ) +/*N*/ { +/*N*/ SwSectionFmt* pFmt = (*pSectionFmtTbl)[ nPos ]; +/*N*/ SwSection* pSection = pFmt->GetSection(); +/*N*/ /// OD 04.10.2002 #102894# +/*N*/ /// remember hidden condition flag of SwSection before changes +/*N*/ bool bOldCondHidden = pSection->IsCondHidden() ? true : false; +/*N*/ +/*N*/ if( *pSection == rSect ) +/*N*/ { +/*N*/ // die Attribute ueberpruefen +/*N*/ BOOL bOnlyAttrChg = FALSE; +/*N*/ if( pAttr && pAttr->Count() ) +/*N*/ { +/*N*/ SfxItemIter aIter( *pAttr ); +/*N*/ USHORT nWhich = aIter.GetCurItem()->Which(); +/*N*/ while( TRUE ) +/*N*/ { +/*N*/ if( pFmt->GetAttr( nWhich ) != *aIter.GetCurItem() ) +/*N*/ { +/*N*/ bOnlyAttrChg = TRUE; +/*N*/ break; +/*N*/ } +/*N*/ +/*?*/ if( aIter.IsAtEnd() ) +/*?*/ break; +/*?*/ nWhich = aIter.NextItem()->Which(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bOnlyAttrChg ) +/*N*/ { +/*N*/ pFmt->SetAttr( *pAttr ); +/*N*/ SetModified(); +/*N*/ } +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ // Teste ob eine gesamte Content-Section (Dokument/TabellenBox/Fly) +/*N*/ // versteckt werden soll, koennen wir zur Zeit nicht !!!! +/*N*/ const SwNodeIndex* pIdx = 0; +/*N*/ { +/*N*/ const SwSectionNode* pSectNd; +/*N*/ if( rSect.IsHidden() && 0 != (pIdx = pFmt->GetCntnt().GetCntntIdx() ) +/*N*/ && 0 != (pSectNd = pIdx->GetNode().GetSectionNode() ) ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ::lcl_CheckEmptyLayFrm( GetNodes(), (SwSection&)rSect, +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ +/*N*/ // #56167# Der LinkFileName koennte auch nur aus Separatoren bestehen +/*N*/ String sCompareString = ::binfilter::cTokenSeperator; +/*N*/ sCompareString += ::binfilter::cTokenSeperator; +/*N*/ BOOL bUpdate = ( !pSection->IsLinkType() && rSect.IsLinkType() ) || +/*N*/ ( rSect.GetLinkFileName().Len() && +/*N*/ rSect.GetLinkFileName() != sCompareString && +/*N*/ rSect.GetLinkFileName() != +/*N*/ pSection->GetLinkFileName()); +/*N*/ +/*N*/ String sSectName( rSect.GetName() ); +/*N*/ if( sSectName != pSection->GetName() ) +/*?*/ GetUniqueSectionName( &sSectName ); +/*N*/ else +/*N*/ sSectName.Erase(); +/*N*/ +/*N*/ /// OD 04.10.2002 #102894# - NOTE +/*N*/ /// In SwSection::operator=(..) class member bCondHiddenFlag is always set to TRUE. +/*N*/ /// IMHO this have to be changed, but I can't estimate the consequences: +/*N*/ /// Either it is set to TRUE using corresponding method <SwSection.SetCondHidden(..)>, +/*N*/ /// or it is set to the value of SwSection which is assigned to it. +/*N*/ /// Discussion with AMA results that the adjustment to the assignment operator +/*N*/ /// could be very risky -> see notes in bug #102894#. +/*N*/ *pSection = rSect; +/*N*/ +/*N*/ if( pAttr ) +/*?*/ pSection->GetFmt()->SetAttr( *pAttr ); +/*N*/ +/*N*/ if( sSectName.Len() ) +/*?*/ pSection->SetName( sSectName ); +/*N*/ +/*N*/ // ist eine Condition gesetzt +/*N*/ if( pSection->IsHidden() && pSection->GetCondition().Len() ) +/*N*/ { +/*?*/ // dann berechne bis zu dieser Position +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwCalc aCalc( *this ); +/*N*/ } +/*N*/ +/*N*/ if( bUpdate ) +/*N*/ pSection->CreateLink( bPreventLinkUpdate ? CREATE_CONNECT : CREATE_UPDATE ); +/*N*/ else if( !pSection->IsLinkType() && pSection->IsConnected() ) +/*N*/ { +/*?*/ pSection->Disconnect(); +/*?*/ GetLinkManager().Remove( &pSection->GetBaseLink() ); +/*N*/ } +/*N*/ +/*N*/ SetModified(); +/*N*/ } + + +/* -----------------19.02.99 09:31------------------- + * LockFrms wurde im InsertSection genutzt, um zu verhindern, dass + * SectionFrms durch das DelFrms zerstoert werden. Dies ist durch + * den Destroy-Listen-Mechanismus ueberfluessig geworden. + * Falls diese Methode doch noch einmal reanimiert wird, bietet es + * sich vielleicht an, beim Entlocken die SectionFrms auf Inhalt zu + * pruefen und dann ggf. zur Zerstoerung anzumelden. + * --------------------------------------------------*/ + +// und dann waren da noch die Fussnoten: +/*N*/ void lcl_DeleteFtn( SwSectionNode *pNd, ULONG nStt, ULONG nEnd ) +/*N*/ { +/*N*/ SwFtnIdxs& rFtnArr = pNd->GetDoc()->GetFtnIdxs(); +/*N*/ if( rFtnArr.Count() ) +/*N*/ { +/*?*/ USHORT nPos; + /*?*/ rFtnArr.SeekEntry( SwNodeIndex( *pNd ), &nPos ); + /*?*/ SwTxtFtn* pSrch; + /*?*/ + /*?*/ // loesche erstmal alle, die dahinter stehen + /*?*/ while( nPos < rFtnArr.Count() && + /*?*/ _SwTxtFtn_GetIndex( (pSrch = rFtnArr[ nPos ]) ) <= nEnd ) + /*?*/ { + /*?*/ // Werden die Nodes nicht geloescht mussen sie bei den Seiten + /*?*/ // abmeldet (Frms loeschen) werden, denn sonst bleiben sie + /*?*/ // stehen (Undo loescht sie nicht!) + /*?*/ pSrch->DelFrms(); + /*?*/ ++nPos; + /*?*/ } + /*?*/ + /*?*/ while( nPos-- && + /*?*/ _SwTxtFtn_GetIndex( (pSrch = rFtnArr[ nPos ]) ) >= nStt ) + /*?*/ { + /*?*/ // Werden die Nodes nicht geloescht mussen sie bei den Seiten + /*?*/ // abmeldet (Frms loeschen) werden, denn sonst bleiben sie + /*?*/ // stehen (Undo loescht sie nicht!) + /*?*/ pSrch->DelFrms(); + /*?*/ } +/*N*/ } +/*N*/ } + +/*N*/ inline BOOL lcl_IsTOXSection( const SwSection& rSection ) +/*N*/ { +/*N*/ return TOX_CONTENT_SECTION == rSection.GetType() || +/*N*/ TOX_HEADER_SECTION == rSection.GetType(); +/*N*/ } + +/*N*/ SwSectionNode* SwNodes::InsertSection( const SwNodeIndex& rNdIdx, +/*N*/ SwSectionFmt& rSectionFmt, +/*N*/ const SwSection& rSection, +/*N*/ const SwNodeIndex* pEnde, +/*N*/ BOOL bInsAtStart, BOOL bCreateFrms ) +/*N*/ { +/*N*/ SwNodeIndex aInsPos( rNdIdx ); +/*N*/ if( !pEnde ) // kein Bereich also neue Section davor/hinter anlegen +/*N*/ { +/*N*/ if( bInsAtStart ) +/*N*/ { +/*?*/ if( !lcl_IsTOXSection( rSection )) +/*?*/ { +/*?*/ do { +/*?*/ aInsPos--; +/*?*/ } while( aInsPos.GetNode().IsSectionNode() ); +/*?*/ aInsPos++; +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ SwNode* pNd; +/*?*/ aInsPos++; +/*?*/ if( !lcl_IsTOXSection( rSection )) +/*?*/ while( aInsPos.GetIndex() < Count() - 1 && +/*?*/ ( pNd = &aInsPos.GetNode())->IsEndNode() && +/*?*/ pNd->FindStartNode()->IsSectionNode()) +/*?*/ aInsPos++; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwSectionNode* pSectNd = new SwSectionNode( aInsPos, rSectionFmt ); +/*N*/ if( pEnde ) +/*N*/ { +/*N*/ // Sonderfall fuer die Reader/Writer +/*N*/ if( &pEnde->GetNode() != &GetEndOfContent() ) +/*N*/ aInsPos = pEnde->GetIndex()+1; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwTxtNode* pCpyTNd = rNdIdx.GetNode().GetTxtNode(); +/*N*/ if( pCpyTNd ) +/*N*/ { +/*N*/ SwTxtNode* pTNd = new SwTxtNode( aInsPos, pCpyTNd->GetTxtColl() ); +/*N*/ if( pCpyTNd->GetpSwAttrSet() ) +/*N*/ { +/*?*/ // Task 70955 - move PageDesc/Break to the first Node of the +/*?*/ // section +/*?*/ const SfxItemSet& rSet = *pCpyTNd->GetpSwAttrSet(); +/*?*/ if( SFX_ITEM_SET == rSet.GetItemState( RES_BREAK ) || +/*?*/ SFX_ITEM_SET == rSet.GetItemState( RES_PAGEDESC )) +/*?*/ { +/*?*/ SfxItemSet aSet( rSet ); +/*?*/ if( bInsAtStart ) +/*?*/ pCpyTNd->ResetAttr( RES_PAGEDESC, RES_BREAK ); +/*?*/ else +/*?*/ { +/*?*/ aSet.ClearItem( RES_PAGEDESC ); +/*?*/ aSet.ClearItem( RES_BREAK ); +/*?*/ } +/*?*/ pTNd->SwCntntNode::SetAttr( aSet ); +/*?*/ } +/*?*/ else +/*?*/ pTNd->SwCntntNode::SetAttr( rSet ); +/*N*/ } +/*N*/ // den Frame anlegen nicht vergessen !! +/*N*/ pCpyTNd->MakeFrms( *pTNd ); +/*N*/ } +/*N*/ else +/*?*/ new SwTxtNode( aInsPos, (SwTxtFmtColl*)GetDoc()->GetDfltTxtFmtColl() ); +/*N*/ } +/*N*/ SwEndNode* pEndNd = new SwEndNode( aInsPos, *pSectNd ); +/*N*/ +/*N*/ pSectNd->GetSection() = rSection; +/*N*/ SwSectionFmt* pSectFmt = pSectNd->GetSection().GetFmt(); +/*N*/ +/*N*/ // Hier bietet sich als Optimierung an, vorhandene Frames nicht zu +/*N*/ // zerstoeren und wieder neu anzulegen, sondern nur umzuhaengen. +/*N*/ BOOL bInsFrm = bCreateFrms && !pSectNd->GetSection().IsHidden() && +/*N*/ GetDoc()->GetRootFrm(); +/*N*/ SwNode2Layout *pNode2Layout = NULL; +/*N*/ if( bInsFrm ) +/*N*/ { +/*N*/ SwNodeIndex aTmp( *pSectNd ); +/*N*/ if( !pSectNd->GetNodes().FindPrvNxtFrmNode( aTmp, pSectNd->EndOfSectionNode() ) ) +/*N*/ // dann sammel mal alle Uppers ein +/*?*/ pNode2Layout = new SwNode2Layout( *pSectNd ); +/*N*/ } +/*N*/ +/*N*/ // jetzt noch bei allen im Bereich den richtigen StartNode setzen +/*N*/ ULONG nEnde = pSectNd->EndOfSectionIndex(); +/*N*/ ULONG nStart = pSectNd->GetIndex()+1; +/*N*/ ULONG nSkipIdx = ULONG_MAX; +/*N*/ for( ULONG n = nStart; n < nEnde; ++n ) +/*N*/ { +/*N*/ SwNode* pNd = (*this)[n]; +/*N*/ +/*N*/ //JP 30.04.99: Bug 65644 - alle in der NodeSection liegenden +/*N*/ // Sections unter die neue haengen +/*N*/ if( ULONG_MAX == nSkipIdx ) +/*N*/ pNd->pStartOfSection = pSectNd; +/*N*/ else if( n >= nSkipIdx ) +/*?*/ nSkipIdx = ULONG_MAX; +/*N*/ +/*N*/ if( pNd->IsStartNode() ) +/*N*/ { +/*?*/ // die Verschachtelung der Formate herstellen! +/*?*/ if( pNd->IsSectionNode() ) +/*?*/ { +/*?*/ ((SwSectionNode*)pNd)->GetSection().GetFmt()-> +/*?*/ SetDerivedFrom( pSectFmt ); +/*?*/ ((SwSectionNode*)pNd)->DelFrms(); +/*?*/ n = pNd->EndOfSectionIndex(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ if( pNd->IsTableNode() ) +/*?*/ ((SwTableNode*)pNd)->DelFrms(); +/*?*/ +/*?*/ if( ULONG_MAX == nSkipIdx ) +/*?*/ nSkipIdx = pNd->EndOfSectionIndex(); +/*?*/ } +/*N*/ } +/*N*/ else if( pNd->IsCntntNode() ) +/*N*/ ((SwCntntNode*)pNd)->DelFrms(); +/*N*/ } +/*N*/ +/*N*/ lcl_DeleteFtn( pSectNd, nStart, nEnde ); +/*N*/ +/*N*/ if( bInsFrm ) +/*N*/ { +/*N*/ if( pNode2Layout ) +/*N*/ { +/*?*/ ULONG nIdx = pSectNd->GetIndex(); +/*?*/ pNode2Layout->RestoreUpperFrms( pSectNd->GetNodes(), nIdx, nIdx + 1 ); +/*?*/ delete pNode2Layout; +/*N*/ } +/*N*/ else +/*N*/ pSectNd->MakeFrms( &aInsPos ); +/*N*/ } +/*N*/ +/*N*/ return pSectNd; +/*N*/ } + +/*N*/ SwSectionNode* SwNode::FindSectionNode() +/*N*/ { +/*N*/ if( IsSectionNode() ) +/*N*/ return GetSectionNode(); +/*N*/ SwStartNode* pTmp = pStartOfSection; +/*N*/ while( !pTmp->IsSectionNode() && pTmp->GetIndex() ) +/*N*/ #if defined( ALPHA ) && defined( UNX ) +/*?*/ pTmp = ((SwNode*)pTmp)->pStartOfSection; +/*N*/ #else +/*N*/ pTmp = pTmp->pStartOfSection; +/*N*/ #endif +/*N*/ return pTmp->GetSectionNode(); +/*N*/ } + + +//--------- +// SwSectionNode +//--------- + +/*N*/ SwSectionNode::SwSectionNode( const SwNodeIndex& rIdx, SwSectionFmt& rFmt ) +/*N*/ : SwStartNode( rIdx, ND_SECTIONNODE ) +/*N*/ { +/*N*/ SwSectionNode* pParent = FindStartNode()->FindSectionNode(); +/*N*/ if( pParent ) +/*N*/ { +/*N*/ // das Format beim richtigen Parent anmelden. +/*N*/ rFmt.SetDerivedFrom( pParent->GetSection().GetFmt() ); +/*N*/ } +/*N*/ pSection = new SwSection( CONTENT_SECTION, rFmt.GetName(), &rFmt ); +/*N*/ +/*N*/ // jetzt noch die Verbindung von Format zum Node setzen +/*N*/ // Modify unterdruecken, interresiert keinen +/*N*/ rFmt.LockModify(); +/*N*/ rFmt.SetAttr( SwFmtCntnt( this ) ); +/*N*/ rFmt.UnlockModify(); +/*N*/ } + +//Hier werden ueberfluessige SectionFrms entfernt + +/*N*/ SwSectionNode::~SwSectionNode() +/*N*/ { +/*N*/ { +/*N*/ SwClientIter aIter( *(pSection->GetFmt()) ); +/*N*/ SwClient *pLast = aIter.GoStart(); +/*N*/ while ( pLast ) +/*N*/ { +/*N*/ if ( pLast->IsA( TYPE(SwFrm) ) ) +/*N*/ { +/*?*/ SwSectionFrm *pSectFrm = (SwSectionFrm*)pLast; +/*?*/ SwSectionFrm::MoveCntntAndDelete( pSectFrm, TRUE ); +/*?*/ pLast = aIter.GoStart(); +/*N*/ } +/*N*/ else +/*N*/ pLast = aIter++; +/*N*/ } +/*N*/ } +/*N*/ SwDoc* pDoc = GetDoc(); +/*N*/ +/*N*/ SwSectionFmt* pFmt = pSection->GetFmt(); +/*N*/ if( pFmt ) +/*N*/ { +/*N*/ // das Attribut entfernen, weil die Section ihr Format loescht +/*N*/ // und falls das Cntnt-Attribut vorhanden ist, die Section aufhebt. +/*N*/ pFmt->LockModify(); +/*N*/ pFmt->ResetAttr( RES_CNTNT ); +/*N*/ pFmt->UnlockModify(); +/*N*/ } +/*N*/ +/*N*/ DELETEZ( pSection ); +/*N*/ } + +// setze ein neues SectionObject. Erstmal nur gedacht fuer die +// neuen VerzeichnisSections. Der geht ueber in den Besitz des Nodes! +/*N*/ void SwSectionNode::SetNewSection( SwSection* pNewSection ) +/*N*/ { +/*N*/ ASSERT( pNewSection, "ohne Pointer geht hier nichts" ); +/*N*/ if( pNewSection ) +/*N*/ { +/*N*/ SwNode2Layout aN2L( *this ); +/*N*/ +/*N*/ // einige Flags sollten ueber nommen werden! +/*N*/ pNewSection->bProtectFlag = pSection->bProtectFlag; +/*N*/ pNewSection->bHiddenFlag = pSection->bHiddenFlag; +/*N*/ pNewSection->bHidden = pSection->bHidden; +/*N*/ pNewSection->bCondHiddenFlag = pSection->bCondHiddenFlag; +/*N*/ +/*N*/ // The section frame contains a pointer to the section. That for, +/*N*/ // the frame must be destroyed before deleting the section. +/*N*/ DelFrms(); +/*N*/ +/*N*/ delete pSection; +/*N*/ pSection = pNewSection; +/*N*/ +/*N*/ ULONG nIdx = GetIndex(); +/*N*/ aN2L.RestoreUpperFrms( GetNodes(), nIdx, nIdx + 1 ); +/*N*/ } +/*N*/ } + +/*N*/ SwFrm *SwSectionNode::MakeFrm() +/*N*/ { +/*N*/ pSection->bHiddenFlag = FALSE; +/*N*/ return new SwSectionFrm( *pSection ); +/*N*/ } + +//Fuer jedes vorkommen im Layout einen SectionFrm anlegen und vor den +//entsprechenden CntntFrm pasten. + +/*N*/ void SwSectionNode::MakeFrms( SwNodeIndex* pIdxBehind, SwNodeIndex* pEndIdx ) +/*N*/ { +/*N*/ ASSERT( pIdxBehind, "kein Index" ); +/*N*/ SwNodes& rNds = GetNodes(); +/*N*/ SwDoc* pDoc = rNds.GetDoc(); +/*N*/ +/*N*/ *pIdxBehind = *this; +/*N*/ +/*N*/ pSection->bHiddenFlag = TRUE; +/*N*/ +/*N*/ if( rNds.IsDocNodes() ) +/*N*/ { +/*N*/ SwNodeIndex *pEnd = pEndIdx ? pEndIdx : +/*N*/ new SwNodeIndex( *EndOfSectionNode(), 1 ); +/*N*/ ::binfilter::MakeFrms( pDoc, *pIdxBehind, *pEnd ); +/*N*/ if( !pEndIdx ) +/*N*/ delete pEnd; +/*N*/ } +/*N*/ +/*N*/ } + +/*N*/ void SwSectionNode::DelFrms() +/*N*/ { +/*N*/ ULONG nStt = GetIndex()+1, nEnd = EndOfSectionIndex(); +/*N*/ if( nStt >= nEnd ) +/*N*/ { +/*?*/ // unser Flag muessen wir noch aktualisieren +/*?*/ // pSection->bHiddenFlag = TRUE; +/*?*/ return ; +/*N*/ } +/*N*/ +/*N*/ SwNodes& rNds = GetNodes(); +/*N*/ pSection->GetFmt()->DelFrms(); +/*N*/ +/*N*/ // unser Flag muessen wir noch aktualisieren +/*N*/ pSection->bHiddenFlag = TRUE; +/*N*/ +/*N*/ // Bug 30582: falls der Bereich in Fly oder TabellenBox ist, dann +/*N*/ // kann er nur "gehiddet" werden, wenn weiterer Content +/*N*/ // vorhanden ist, der "Frames" haelt. Sonst hat der +/*N*/ // Fly/TblBox-Frame keinen Lower !!! +/*N*/ { +/*N*/ SwNodeIndex aIdx( *this ); +/*N*/ if( !rNds.GoPrevSection( &aIdx, TRUE, FALSE ) || +/*N*/ !CheckNodesRange( *this, aIdx, TRUE ) || +/*N*/ !lcl_IsInSameTblBox( rNds, *this, aIdx )) +/*N*/ { +/*N*/ aIdx = *EndOfSectionNode(); +/*N*/ if( !rNds.GoNextSection( &aIdx, TRUE, FALSE ) || +/*N*/ !CheckNodesRange( *EndOfSectionNode(), aIdx, TRUE ) || +/*N*/ !lcl_IsInSameTblBox( rNds, *EndOfSectionNode(), aIdx )) +/*?*/ pSection->bHiddenFlag = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ String SwDoc::GetUniqueSectionName( const String* pChkStr ) const +/*N*/ { +/*N*/ ResId aId( STR_REGION_DEFNAME, *pSwResMgr ); +/*N*/ String aName( aId ); +/*N*/ xub_StrLen nNmLen = aName.Len(); +/*N*/ +/*N*/ USHORT nNum, nTmp, nFlagSize = ( pSectionFmtTbl->Count() / 8 ) +2; +/*N*/ BYTE* pSetFlags = new BYTE[ nFlagSize ]; +/*N*/ memset( pSetFlags, 0, nFlagSize ); +/*N*/ +/*N*/ const SwSectionNode* pSectNd; + USHORT n=0; +/*N*/ for( n = 0; n < pSectionFmtTbl->Count(); ++n ) +/*N*/ if( 0 != ( pSectNd = (*pSectionFmtTbl)[ n ]->GetSectionNode( FALSE ) )) +/*N*/ { +/*N*/ const String& rNm = pSectNd->GetSection().GetName(); +/*N*/ if( rNm.Match( aName ) == nNmLen ) +/*N*/ { +/*?*/ // Nummer bestimmen und das Flag setzen +/*?*/ nNum = rNm.Copy( nNmLen ).ToInt32(); +/*?*/ if( nNum-- && nNum < pSectionFmtTbl->Count() ) +/*?*/ pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 )); +/*N*/ } +/*N*/ if( pChkStr && pChkStr->Equals( rNm ) ) +/*?*/ pChkStr = 0; +/*N*/ } +/*N*/ +/*N*/ if( !pChkStr ) +/*N*/ { +/*?*/ // alle Nummern entsprechend geflag, also bestimme die richtige Nummer +/*?*/ nNum = pSectionFmtTbl->Count(); +/*?*/ for( n = 0; n < nFlagSize; ++n ) +/*?*/ if( 0xff != ( nTmp = pSetFlags[ n ] )) +/*?*/ { +/*?*/ // also die Nummer bestimmen +/*?*/ nNum = n * 8; +/*?*/ while( nTmp & 1 ) +/*?*/ ++nNum, nTmp >>= 1; +/*?*/ break; +/*?*/ } +/*?*/ +/*N*/ } +/*N*/ delete [] pSetFlags; +/*N*/ if( pChkStr ) +/*N*/ return *pChkStr; +/*?*/ return aName += String::CreateFromInt32( ++nNum ); +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_ndtbl.cxx b/binfilter/bf_sw/source/core/docnode/sw_ndtbl.cxx new file mode 100644 index 000000000000..a4a40b52e65b --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_ndtbl.cxx @@ -0,0 +1,920 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER +#ifdef WTC +#define private public +#endif + +#include <hintids.hxx> + + +#include <bf_svx/lrspitem.hxx> + +#include <fmtfsize.hxx> + +#include <horiornt.hxx> + +#include <fmtornt.hxx> +#include <fmtfordr.hxx> +#include <fmtlsplt.hxx> + +#include <doc.hxx> +#include <cntfrm.hxx> +#include <hints.hxx> +#include <poolfmt.hxx> +#include <tabfrm.hxx> +#include <tblafmt.hxx> +#include <cellatr.hxx> +#include <swtblfmt.hxx> +#include <docary.hxx> +#include <redline.hxx> +#include <tblrwcl.hxx> +#include <editsh.hxx> + +#include <node2lay.hxx> + +#include <comcore.hrc> + +#include "docsh.hxx" + +#ifdef _MSAVE_HXX +#endif + +#ifdef LINUX +#endif + +#include <ndtxt.hxx> +namespace binfilter { + +const sal_Unicode T2T_PARA = 0x0a; + + +// steht im gctable.cxx + + +/*N*/ void lcl_SetDfltBoxAttr( SwFrmFmt& rFmt, BYTE nId ) +/*N*/ { +/*N*/ BOOL bTop = FALSE, bBottom = FALSE, bLeft = FALSE, bRight = FALSE; +/*N*/ switch ( nId ) +/*N*/ { +/*?*/ case 0: bTop = bBottom = bLeft = TRUE; break; +/*N*/ case 1: bTop = bBottom = bLeft = bRight = TRUE; break; +/*?*/ case 2: bBottom = bLeft = TRUE; break; +/*?*/ case 3: bBottom = bLeft = bRight = TRUE; break; +/*N*/ } +/*N*/ +/*N*/ const BOOL bHTML = rFmt.GetDoc()->IsHTMLMode(); +/*N*/ Color aCol( bHTML ? COL_GRAY : COL_BLACK ); +/*N*/ SvxBorderLine aLine( &aCol, DEF_LINE_WIDTH_0 ); +/*N*/ if ( bHTML ) +/*N*/ { +/*?*/ aLine.SetOutWidth( DEF_DOUBLE_LINE7_OUT ); +/*?*/ aLine.SetInWidth ( DEF_DOUBLE_LINE7_IN ); +/*?*/ aLine.SetDistance( DEF_DOUBLE_LINE7_DIST); +/*N*/ } +/*N*/ SvxBoxItem aBox; aBox.SetDistance( 55 ); +/*N*/ if ( bTop ) +/*N*/ aBox.SetLine( &aLine, BOX_LINE_TOP ); +/*N*/ if ( bBottom ) +/*N*/ aBox.SetLine( &aLine, BOX_LINE_BOTTOM ); +/*N*/ if ( bLeft ) +/*N*/ aBox.SetLine( &aLine, BOX_LINE_LEFT ); +/*N*/ if ( bRight ) +/*N*/ aBox.SetLine( &aLine, BOX_LINE_RIGHT ); +/*N*/ rFmt.SetAttr( aBox ); +/*N*/ } + + +/* --> #109161# */ +static bool lcl_IsItemSet(const SwCntntNode & rNode, USHORT which) +{ + bool bResult = false; + + if (SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState(which)) + bResult = true; + + return bResult; +} + +/* <-- #109161# */ + +/*N*/ SwTableBoxFmt *lcl_CreateDfltBoxFmt( SwDoc &rDoc, SvPtrarr &rBoxFmtArr, +/*N*/ USHORT nCols, BYTE nId ) +/*N*/ { +/*N*/ if ( !rBoxFmtArr[nId] ) +/*N*/ { +/*N*/ SwTableBoxFmt* pBoxFmt = rDoc.MakeTableBoxFmt(); +/*N*/ if( USHRT_MAX != nCols ) +/*N*/ pBoxFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, +/*N*/ USHRT_MAX / nCols, 0 )); +/*N*/ ::binfilter::lcl_SetDfltBoxAttr( *pBoxFmt, nId ); +/*N*/ rBoxFmtArr.Replace( pBoxFmt, nId ); +/*N*/ } +/*N*/ return (SwTableBoxFmt*)rBoxFmtArr[nId]; +/*N*/ } + + +/*N*/ SwTableNode* SwDoc::IsIdxInTbl(const SwNodeIndex& rIdx) +/*N*/ { +/*N*/ SwTableNode* pTableNd = 0; +/*N*/ ULONG nIndex = rIdx.GetIndex(); +/*N*/ do { +/*N*/ SwNode* pNd = (SwNode*)GetNodes()[ nIndex ]->StartOfSectionNode(); +/*N*/ if( 0 != ( pTableNd = pNd->GetTableNode() ) ) +/*?*/ break; +/*N*/ +/*N*/ nIndex = pNd->GetIndex(); +/*N*/ } while ( nIndex ); +/*N*/ return pTableNd; +/*N*/ } + + +// --------------- einfuegen einer neuen Box -------------- + + // fuege in der Line, vor der InsPos eine neue Box ein. + + BOOL SwNodes::InsBoxen( SwTableNode* pTblNd, + SwTableLine* pLine, + SwTableBoxFmt* pBoxFmt, + SwTxtFmtColl* pTxtColl, + SwAttrSet* pAutoAttr, + USHORT nInsPos, + USHORT nCnt ) + { + if( !nCnt ) + return FALSE; + ASSERT( pLine, "keine gueltige Zeile" ); + + // Index hinter die letzte Box der Line + ULONG nIdxPos; + SwTableBox *pPrvBox = 0, *pNxtBox = 0; + if( pLine->GetTabBoxes().Count() ) + { + if( nInsPos < pLine->GetTabBoxes().Count() ) + { + if( 0 == (pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable(), + pLine->GetTabBoxes()[ nInsPos ] ))) + pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable() ); + } + else if( 0 == ( pNxtBox = pLine->FindNextBox( pTblNd->GetTable(), + pLine->GetTabBoxes()[ nInsPos-1 ] ))) + pNxtBox = pLine->FindNextBox( pTblNd->GetTable() ); + } + else if( 0 == ( pNxtBox = pLine->FindNextBox( pTblNd->GetTable() ))) + pPrvBox = pLine->FindPreviousBox( pTblNd->GetTable() ); + + if( !pPrvBox && !pNxtBox ) + { + BOOL bSetIdxPos = TRUE; + if( pTblNd->GetTable().GetTabLines().Count() && !nInsPos ) + { + const SwTableLine* pTblLn = pLine; + while( pTblLn->GetUpper() ) + pTblLn = pTblLn->GetUpper()->GetUpper(); + + if( pTblNd->GetTable().GetTabLines()[ 0 ] == pTblLn ) + { + // also vor die erste Box der Tabelle + while( ( pNxtBox = pLine->GetTabBoxes()[0])->GetTabLines().Count() ) + pLine = pNxtBox->GetTabLines()[0]; + nIdxPos = pNxtBox->GetSttIdx(); + bSetIdxPos = FALSE; + } + } + if( bSetIdxPos ) + // Tabelle ohne irgendeinen Inhalt oder am Ende, also vors Ende + nIdxPos = pTblNd->EndOfSectionIndex(); + } + else if( pNxtBox ) // es gibt einen Nachfolger + nIdxPos = pNxtBox->GetSttIdx(); + else // es gibt einen Vorgaenger + nIdxPos = pPrvBox->GetSttNd()->EndOfSectionIndex() + 1; + + SwNodeIndex aEndIdx( *this, nIdxPos ); + for( USHORT n = 0; n < nCnt; ++n ) + { + SwStartNode* pSttNd = new SwStartNode( aEndIdx, ND_STARTNODE, + SwTableBoxStartNode ); + pSttNd->pStartOfSection = pTblNd; + SwEndNode* pEndNd = new SwEndNode( aEndIdx, *pSttNd ); + + pPrvBox = new SwTableBox( pBoxFmt, *pSttNd, pLine ); + + SwTableBoxes & rTabBoxes = pLine->GetTabBoxes(); + USHORT nRealInsPos = nInsPos + n; + if (nRealInsPos > rTabBoxes.Count()) + nRealInsPos = rTabBoxes.Count(); + + rTabBoxes.C40_INSERT( SwTableBox, pPrvBox, nRealInsPos ); + + if( NO_NUMBERING == pTxtColl->GetOutlineLevel() + //FEATURE::CONDCOLL + && RES_CONDTXTFMTCOLL != pTxtColl->Which() + //FEATURE::CONDCOLL + ) + new SwTxtNode( SwNodeIndex( *pSttNd->EndOfSectionNode() ), + pTxtColl, pAutoAttr ); + else + { + // Outline-Numerierung richtig behandeln !!! + SwTxtNode* pTNd = new SwTxtNode( + SwNodeIndex( *pSttNd->EndOfSectionNode() ), + (SwTxtFmtColl*)GetDoc()->GetDfltTxtFmtColl(), + pAutoAttr ); + pTNd->ChgFmtColl( pTxtColl ); + } + } + return TRUE; + } + +// --------------- einfuegen einer neuen Tabelle -------------- + +/*N*/ const SwTable* SwDoc::InsertTable( const SwPosition& rPos, USHORT nRows, +/*N*/ USHORT nCols, SwHoriOrient eAdjust, +/*N*/ USHORT nInsTblFlags, +/*N*/ const SwTableAutoFmt* pTAFmt, +/*N*/ const SvUShorts* pColArr, +/*N*/ BOOL bCalledFromShell ) +/*N*/ { +/*N*/ ASSERT( nRows, "Tabelle ohne Zeile?" ); +/*N*/ ASSERT( nCols, "Tabelle ohne Spalten?" ); +/*N*/ +/*N*/ { +/*N*/ // nicht in Fussnoten kopieren !! +/*N*/ if( rPos.nNode < GetNodes().GetEndOfInserts().GetIndex() && +/*N*/ rPos.nNode >= GetNodes().GetEndOfInserts().StartOfSectionIndex() ) +/*?*/ return 0; +/*N*/ +/*N*/ // sollte das ColumnArray die falsche Anzahl haben wird es ignoriert! +/*N*/ if( pColArr && +/*N*/ (nCols + ( HORI_NONE == eAdjust ? 2 : 1 )) != pColArr->Count() ) +/*?*/ pColArr = 0; +/*N*/ } +/*N*/ +/*N*/ // fuege erstmal die Nodes ein +/*N*/ // hole das Auto-Format fuer die Tabelle +/*N*/ SwTxtFmtColl *pBodyColl = GetTxtCollFromPool( RES_POOLCOLL_TABLE ), +/*N*/ *pHeadColl = pBodyColl; +/*N*/ +/*N*/ BOOL bDfltBorders = nInsTblFlags & DEFAULT_BORDER; +/*N*/ +/*N*/ if( (nInsTblFlags & HEADLINE) && (1 != nRows || !bDfltBorders) ) +/*?*/ pHeadColl = GetTxtCollFromPool( RES_POOLCOLL_TABLE_HDLN ); +/*N*/ +/*N*/ /* #106283# Save content node to extract FRAMEDIR from. */ +/*N*/ const SwCntntNode * pCntntNd = rPos.nNode.GetNode().GetCntntNode(); +/*N*/ + /* #109161# If we are called from a shell pass the attrset from + pCntntNd (aka the node the table is inserted at) thus causing + SwNodes::InsertTable to propagate an adjust item if + necessary. */ +/*N*/ SwTableNode *pTblNd = GetNodes().InsertTable +/*N*/ ( rPos.nNode, nCols, pBodyColl, nRows, pHeadColl, +/*N*/ bCalledFromShell ? &pCntntNd->GetSwAttrSet() : 0 ); +/*N*/ +/*N*/ // dann erstelle die Box/Line/Table-Struktur +/*N*/ SwTableLineFmt* pLineFmt = MakeTableLineFmt(); +/*N*/ SwTableFmt* pTableFmt = MakeTblFrmFmt( GetUniqueTblName(), GetDfltFrmFmt() ); +/*N*/ + /* #106283# If the node to insert the table at is a context node and has a + non-default FRAMEDIR propagate it to the table. */ +/*N*/ if (pCntntNd) +/*N*/ { +/*N*/ const SwAttrSet & aNdSet = pCntntNd->GetSwAttrSet(); +/*N*/ const SfxPoolItem *pItem = NULL; +/*N*/ +/*N*/ if (SFX_ITEM_SET == aNdSet.GetItemState( RES_FRAMEDIR, TRUE, &pItem ) +/*N*/ && pItem != NULL) +/*N*/ { +/*N*/ pTableFmt->SetAttr( *pItem ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Orientation am Fmt der Table setzen +/*N*/ pTableFmt->SetAttr( SwFmtHoriOrient( 0, eAdjust ) ); +/*N*/ // alle Zeilen haben die Fill-Order von links nach rechts ! +/*N*/ pLineFmt->SetAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT )); +/*N*/ +/*N*/ // die Tabelle bekommt USHRT_MAX als default SSize +/*N*/ SwTwips nWidth = USHRT_MAX; +/*N*/ if( pColArr ) +/*N*/ { +/*?*/ USHORT nSttPos = (*pColArr)[ 0 ]; +/*?*/ USHORT nLastPos = (*pColArr)[ USHORT(pColArr->Count()-1)]; +/*?*/ if( HORI_NONE == eAdjust ) +/*?*/ { +/*?*/ USHORT nFrmWidth = nLastPos; +/*?*/ nLastPos = (*pColArr)[ USHORT(pColArr->Count()-2)]; +/*?*/ pTableFmt->SetAttr( SvxLRSpaceItem( nSttPos, nFrmWidth - nLastPos ) ); +/*?*/ } +/*?*/ nWidth = nLastPos - nSttPos; +/*N*/ } +/*N*/ pTableFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth )); +/*N*/ if( !(nInsTblFlags & SPLIT_LAYOUT) ) +/*?*/ pTableFmt->SetAttr( SwFmtLayoutSplit( FALSE )); +/*N*/ +/*N*/ // verschiebe ggfs. die harten PageDesc/PageBreak Attribute: +/*N*/ SwCntntNode* pNextNd = GetNodes()[ pTblNd->EndOfSectionIndex()+1 ] +/*N*/ ->GetCntntNode(); +/*N*/ if( pNextNd && pNextNd->GetpSwAttrSet() ) +/*N*/ { +/*?*/ SwAttrSet* pNdSet = pNextNd->GetpSwAttrSet(); +/*?*/ const SfxPoolItem *pItem; +/*?*/ if( SFX_ITEM_SET == pNdSet->GetItemState( RES_PAGEDESC, FALSE, +/*?*/ &pItem ) ) +/*?*/ { +/*?*/ pTableFmt->SetAttr( *pItem ); +/*?*/ pNextNd->ResetAttr( RES_PAGEDESC ); +/*?*/ pNdSet = pNextNd->GetpSwAttrSet(); +/*?*/ } +/*?*/ if( pNdSet && SFX_ITEM_SET == pNdSet->GetItemState( RES_BREAK, FALSE, +/*?*/ &pItem ) ) +/*?*/ { +/*?*/ pTableFmt->SetAttr( *pItem ); +/*?*/ pNextNd->ResetAttr( RES_BREAK ); +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ SwTable * pNdTbl = &pTblNd->GetTable(); +/*N*/ pTableFmt->Add( pNdTbl ); // das Frame-Format setzen +/*N*/ +/*N*/ pNdTbl->SetHeadlineRepeat( HEADLINE_REPEAT == (nInsTblFlags & HEADLINE_REPEAT) ); +/*N*/ +/*N*/ SvPtrarr aBoxFmtArr( 0, 16 ); +/*N*/ SwTableBoxFmt* pBoxFmt = 0; +/*N*/ if( !bDfltBorders && !pTAFmt ) +/*N*/ { +/*?*/ pBoxFmt = MakeTableBoxFmt(); +/*?*/ pBoxFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX / nCols, 0 )); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const USHORT nBoxArrLen = pTAFmt ? 16 : 4; +/*N*/ for( USHORT i = 0; i < nBoxArrLen; ++i ) +/*N*/ aBoxFmtArr.Insert( (void*)0, i ); +/*N*/ } +/*N*/ SfxItemSet aCharSet( GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END-1 ); +/*N*/ +/*N*/ SwNodeIndex aNdIdx( *pTblNd, 1 ); // auf den ersten Box-StartNode +/*N*/ SwTableLines& rLines = pNdTbl->GetTabLines(); +/*N*/ for( USHORT n = 0; n < nRows; ++n ) +/*N*/ { +/*N*/ SwTableLine* pLine = new SwTableLine( pLineFmt, nCols, 0 ); +/*N*/ rLines.C40_INSERT( SwTableLine, pLine, n ); +/*N*/ SwTableBoxes& rBoxes = pLine->GetTabBoxes(); +/*N*/ for( USHORT i = 0; i < nCols; ++i ) +/*N*/ { +/*N*/ SwTableBoxFmt *pBoxF; +/*N*/ if( pTAFmt ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 BYTE nId = !n ? 0 : (( n+1 == nRows ) +/*N*/ } +/*N*/ else if( bDfltBorders ) +/*N*/ { +/*N*/ BYTE nBoxId = (i < nCols - 1 ? 0 : 1) + (n ? 2 : 0 ); +/*N*/ pBoxF = ::binfilter::lcl_CreateDfltBoxFmt( *this, aBoxFmtArr, nCols, nBoxId); +/*N*/ } +/*N*/ else +/*?*/ pBoxF = pBoxFmt; +/*N*/ +/*N*/ // fuer AutoFormat bei der Eingabe: beim Einfuegen der Tabelle +/*N*/ // werden gleich die Spalten gesetzt. Im Array stehen die +/*N*/ // Positionen der Spalten!! (nicht deren Breite!) +/*N*/ if( pColArr ) +/*N*/ { +/*?*/ nWidth = (*pColArr)[ USHORT(i + 1) ] - (*pColArr)[ i ]; +/*?*/ if( pBoxF->GetFrmSize().GetWidth() != nWidth ) +/*?*/ { +/*?*/ if( pBoxF->GetDepends() ) // neues Format erzeugen! +/*?*/ { +/*?*/ SwTableBoxFmt *pNewFmt = MakeTableBoxFmt(); +/*?*/ *pNewFmt = *pBoxF; +/*?*/ pBoxF = pNewFmt; +/*?*/ } +/*?*/ pBoxF->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth )); +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ SwTableBox *pBox = new SwTableBox( pBoxF, aNdIdx, pLine); +/*N*/ rBoxes.C40_INSERT( SwTableBox, pBox, i ); +/*N*/ aNdIdx += 3; // StartNode, TextNode, EndNode == 3 Nodes +/*N*/ } +/*N*/ } +/*N*/ // und Frms einfuegen. +/*N*/ GetNodes().GoNext( &aNdIdx ); // zum naechsten ContentNode +/*N*/ pTblNd->MakeFrms( &aNdIdx ); +/*N*/ +/*N*/ if( IsRedlineOn() || (!IsIgnoreRedline() && pRedlineTbl->Count() )) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwPaM aPam( *pTblNd->EndOfSectionNode(), *pTblNd, 1 ); +/*N*/ } +/*N*/ +/*N*/ SetModified(); +/*N*/ return pNdTbl; +/*N*/ } + +/*N*/ SwTableNode* SwNodes::InsertTable( const SwNodeIndex& rNdIdx, +/*N*/ USHORT nBoxes, +/*N*/ SwTxtFmtColl* pCntntTxtColl, +/*N*/ USHORT nLines, +/*N*/ SwTxtFmtColl* pHeadlineTxtColl, +/*N*/ const SwAttrSet * pAttrSet) +/*N*/ { +/*N*/ if( !nBoxes ) +/*?*/ return 0; +/*N*/ +/*N*/ // wenn Lines angegeben, erzeuge die Matrix aus Lines & Boxen +/*N*/ if( !pHeadlineTxtColl || !nLines ) +/*N*/ pHeadlineTxtColl = pCntntTxtColl; +/*N*/ +/*N*/ SwTableNode * pTblNd = new SwTableNode( rNdIdx ); +/*N*/ SwEndNode* pEndNd = new SwEndNode( rNdIdx, *pTblNd ); +/*N*/ +/*N*/ if( !nLines ) // fuer die FOR-Schleife +/*N*/ ++nLines; +/*N*/ +/*N*/ SwNodeIndex aIdx( *pEndNd ); +/*N*/ register SwTxtFmtColl* pTxtColl = pHeadlineTxtColl; +/*N*/ for( register USHORT nL = 0; nL < nLines; ++nL ) +/*N*/ { +/*N*/ for( register USHORT nB = 0; nB < nBoxes; ++nB ) +/*N*/ { +/*N*/ SwStartNode* pSttNd = new SwStartNode( aIdx, ND_STARTNODE, +/*N*/ SwTableBoxStartNode ); +/*N*/ pSttNd->pStartOfSection = pTblNd; + + /** #109161# If there is no adjust item in pTxtColl + propagate any existing adjust item in pAttrSet to the + newly created context node in the new cell. + */ +/*N*/ SwTxtNode * pTmpNd = new SwTxtNode( aIdx, pTxtColl ); +/*N*/ +/*N*/ const SfxPoolItem * pItem = NULL; +/*N*/ +/*N*/ if (! lcl_IsItemSet(*pTmpNd, RES_PARATR_ADJUST) && +/*N*/ pAttrSet != NULL && +/*N*/ SFX_ITEM_SET == pAttrSet->GetItemState( RES_PARATR_ADJUST, TRUE, +/*N*/ &pItem) +/*N*/ ) +/*N*/ { +/*N*/ static_cast<SwCntntNode *>(pTmpNd)->SetAttr(*pItem); +/*N*/ } +/*N*/ +/*N*/ new SwEndNode( aIdx, *pSttNd ); +/*N*/ } +/*N*/ pTxtColl = pCntntTxtColl; +/*N*/ } +/*N*/ return pTblNd; +/*N*/ } + + +//---------------- Text -> Tabelle ----------------------- + + + +//---------------- Tabelle -> Text ----------------------- + + + +// -- benutze die ForEach Methode vom PtrArray um aus einer Tabelle wieder +// Text zuerzeugen. (Die Boxen koennen auch noch Lines enthalten !!) + +// forward deklarieren damit sich die Lines und Boxen rekursiv aufrufen +// koennen. + + + + + + + +// ----- einfuegen von Spalten/Zeilen ------------------------ + + + + + +// ----- loeschen von Spalten/Zeilen ------------------------ + + + + + +// ---------- teilen / zusammenfassen von Boxen in der Tabelle -------- + +/*N*/ BOOL SwDoc::SplitTbl( const SwSelBoxes& rBoxes, sal_Bool bVert, USHORT nCnt, +/*N*/ sal_Bool bSameHeight ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 +/*N*/ } + + + + + +// ------------------------------------------------------- + +//--------- +// SwTableNode +//--------- + +/*N*/ SwTableNode::SwTableNode( const SwNodeIndex& rIdx ) +/*N*/ : SwStartNode( rIdx, ND_TABLENODE ) +/*N*/ { +/*N*/ pTable = new SwTable( 0 ); +/*N*/ } + +/*M*/ SwTableNode::~SwTableNode() +/*M*/ { +/*M*/ //don't forget to notify uno wrappers +/*M*/ SwFrmFmt* pTblFmt = GetTable().GetFrmFmt(); +/*M*/ SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, +/*M*/ pTblFmt ); +/*M*/ pTblFmt->Modify( &aMsgHint, &aMsgHint ); +/*M*/ DelFrms(); +/*M*/ delete pTable; +/*M*/ } + +/*N*/ SwTabFrm *SwTableNode::MakeFrm() +/*N*/ { +/*N*/ return new SwTabFrm( *pTable ); +/*N*/ } + +//Fuer jede Shell einen TblFrm anlegen und vor den entsprechenden +//CntntFrm pasten. + +/*N*/ void SwTableNode::MakeFrms( SwNodeIndex* pIdxBehind ) +/*N*/ { +/*N*/ ASSERT( pIdxBehind, "kein Index" ); +/*N*/ *pIdxBehind = *this; +/*N*/ SwNode *pNd = GetNodes().FindPrvNxtFrmNode( *pIdxBehind, EndOfSectionNode() ); +/*N*/ if( !pNd ) +/*N*/ return ; +/*N*/ +/*N*/ // liegt der gefundene ContentNode vor oder hinter der Tabelle ? +/*N*/ BOOL bBehind = EndOfSectionIndex() < pIdxBehind->GetIndex(); +/*N*/ +/*N*/ SwFrm *pFrm, *pNew; +/*N*/ +/*N*/ SwNode2Layout aNode2Layout( *pNd, GetIndex() ); +/*N*/ while( 0 != (pFrm = aNode2Layout.NextFrm()) ) +/*N*/ { +/*N*/ pNew = MakeFrm(); +/*N*/ pNew->Paste( pFrm->GetUpper(), bBehind ? pFrm : pFrm->GetNext() ); +/*N*/ ((SwTabFrm*)pNew)->RegistFlys(); +/*N*/ } +/*N*/ } + +/*N*/ void SwTableNode::DelFrms() +/*N*/ { +/*N*/ //Erstmal die TabFrms ausschneiden und deleten, die Columns und Rows +/*N*/ //nehmen sie mit in's Grab. +/*N*/ //Die TabFrms haengen am FrmFmt des SwTable. +/*N*/ //Sie muessen etwas umstaendlich zerstort werden, damit die Master +/*N*/ //die Follows mit in's Grab nehmen. +/*N*/ +/*N*/ SwClientIter aIter( *(pTable->GetFrmFmt()) ); +/*N*/ SwClient *pLast = aIter.GoStart(); +/*N*/ while ( pLast ) +/*N*/ { +/*N*/ BOOL bAgain = FALSE; +/*N*/ if ( pLast->IsA( TYPE(SwFrm) ) ) +/*N*/ { +/*N*/ SwTabFrm *pFrm = (SwTabFrm*)pLast; +/*N*/ if ( !pFrm->IsFollow() ) +/*N*/ { +/*N*/ while ( pFrm->HasFollow() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pFrm->JoinAndDelFollows(); +/*N*/ pFrm->Cut(); +/*N*/ delete pFrm; +/*N*/ bAgain = TRUE; +/*N*/ } +/*N*/ } +/*N*/ pLast = bAgain ? aIter.GoStart() : aIter++; +/*N*/ } +/*N*/ } + + +/*N*/ void SwTableNode::SetNewTable( SwTable* pNewTable, BOOL bNewFrames ) +/*N*/ { +DBG_BF_ASSERT(0, "STRIP"); //STRIP001 //STRIP001 DelFrms(); +/*N*/ } + + // setze das TabelleAttribut Undo auf: + + + +/* -----------------18.07.98 11:45------------------- + * Direktzugriff fuer UNO + * --------------------------------------------------*/ + +void SwCollectTblLineBoxes::AddBox( const SwTableBox& rBox ) +{ + aPosArr.Insert( nWidth, aPosArr.Count() ); + SwTableBox* p = (SwTableBox*)&rBox; + aBoxes.Insert( p, aBoxes.Count() ); + nWidth += (USHORT)rBox.GetFrmFmt()->GetFrmSize().GetWidth(); +} + +const SwTableBox* SwCollectTblLineBoxes::GetBoxOfPos( const SwTableBox& rBox ) +{ + const SwTableBox* pRet = 0; + if( aPosArr.Count() ) + { + USHORT n; + for( n = 0; n < aPosArr.Count(); ++n ) + if( aPosArr[ n ] == nWidth ) + break; + else if( aPosArr[ n ] > nWidth ) + { + if( n ) + --n; + break; + } + + if( n >= aPosArr.Count() ) + --n; + + nWidth += (USHORT)rBox.GetFrmFmt()->GetFrmSize().GetWidth(); + pRet = aBoxes[ n ]; + } + return pRet; +} + +BOOL lcl_Line_CollectBox( const SwTableLine*& rpLine, void* pPara ) +{ + SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara; + if( pSplPara->IsGetValues() ) + ((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &::binfilter::lcl_Box_CollectBox, pPara ); + else + ((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &::binfilter::lcl_BoxSetSplitBoxFmts, pPara ); + return TRUE; +} + +BOOL lcl_Box_CollectBox( const SwTableBox*& rpBox, void* pPara ) +{ + SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara; + USHORT nLen = rpBox->GetTabLines().Count(); + if( nLen ) + { + // dann mit der richtigen Line weitermachen + if( pSplPara->IsGetFromTop() ) + nLen = 0; + else + --nLen; + + const SwTableLine* pLn = rpBox->GetTabLines()[ nLen ]; + lcl_Line_CollectBox( pLn, pPara ); + } + else + pSplPara->AddBox( *rpBox ); + return TRUE; +} + +BOOL lcl_BoxSetSplitBoxFmts( const SwTableBox*& rpBox, void* pPara ) +{ + SwCollectTblLineBoxes* pSplPara = (SwCollectTblLineBoxes*)pPara; + USHORT nLen = rpBox->GetTabLines().Count(); + if( nLen ) + { + // dann mit der richtigen Line weitermachen + if( pSplPara->IsGetFromTop() ) + nLen = 0; + else + --nLen; + + const SwTableLine* pLn = rpBox->GetTabLines()[ nLen ]; + lcl_Line_CollectBox( pLn, pPara ); + } + else + { + const SwTableBox* pSrcBox = pSplPara->GetBoxOfPos( *rpBox ); + SwFrmFmt* pFmt = pSrcBox->GetFrmFmt(); + SwTableBox* pBox = (SwTableBox*)rpBox; + + if( HEADLINE_BORDERCOPY == pSplPara->GetMode() ) + { + const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox(); + if( !rBoxItem.GetTop() ) + { + SvxBoxItem aNew( rBoxItem ); + aNew.SetLine( pFmt->GetBox().GetBottom(), BOX_LINE_TOP ); + if( aNew != rBoxItem ) + pBox->ClaimFrmFmt()->SetAttr( aNew ); + } + } + else + { +USHORT __FAR_DATA aTableSplitBoxSetRange[] = { + RES_LR_SPACE, RES_UL_SPACE, + RES_BACKGROUND, RES_SHADOW, + RES_PROTECT, RES_PROTECT, + RES_VERT_ORIENT, RES_VERT_ORIENT, + 0 }; + SfxItemSet aTmpSet( pFmt->GetDoc()->GetAttrPool(), + aTableSplitBoxSetRange ); + aTmpSet.Put( pFmt->GetAttrSet() ); + if( aTmpSet.Count() ) + pBox->ClaimFrmFmt()->SetAttr( aTmpSet ); + + if( HEADLINE_BOXATRCOLLCOPY == pSplPara->GetMode() ) + { + SwNodeIndex aIdx( *pSrcBox->GetSttNd(), 1 ); + SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); + if( !pCNd ) + pCNd = aIdx.GetNodes().GoNext( &aIdx ); + aIdx = *pBox->GetSttNd(); + SwCntntNode* pDNd = aIdx.GetNodes().GoNext( &aIdx ); + + // nur wenn der Node alleine in der Section steht + if( 2 == pDNd->EndOfSectionIndex() - + pDNd->StartOfSectionIndex() ) + { + pDNd->ChgFmtColl( pCNd->GetFmtColl() ); + } + } + + // bedingte Vorlage beachten + pBox->GetSttNd()->CheckSectionCondColl(); + } + } + return TRUE; +} + + + +// und die Umkehrung davon. rPos muss in der Tabelle stehen, die bestehen +// bleibt. Das Flag besagt ob die aktuelle mit der davor oder dahinter +// stehenden vereint wird. + + +// ------------------------------------------------------------------- + + +// -- benutze die ForEach Methode vom PtrArray + +// forward deklarieren damit sich die Lines und Boxen rekursiv aufrufen +// koennen. + + + + + // AutoFormat fuer die Tabelle/TabellenSelection + + + // Erfrage wie attributiert ist + +/*N*/ String SwDoc::GetUniqueTblName() const +/*N*/ { +/*N*/ ResId aId( STR_TABLE_DEFNAME, *pSwResMgr ); +/*N*/ String aName( aId ); +/*N*/ xub_StrLen nNmLen = aName.Len(); +/*N*/ +/*N*/ USHORT nNum, nTmp, nFlagSize = ( pTblFrmFmtTbl->Count() / 8 ) +2; +/*N*/ BYTE* pSetFlags = new BYTE[ nFlagSize ]; +/*N*/ memset( pSetFlags, 0, nFlagSize ); +/*N*/ + USHORT n=0; +/*N*/ for( n = 0; n < pTblFrmFmtTbl->Count(); ++n ) +/*N*/ { +/*N*/ const SwFrmFmt* pFmt = (*pTblFrmFmtTbl)[ n ]; +/*N*/ if( !pFmt->IsDefault() && IsUsed( *pFmt ) && +/*N*/ pFmt->GetName().Match( aName ) == nNmLen ) +/*N*/ { +/*N*/ // Nummer bestimmen und das Flag setzen +/*N*/ nNum = pFmt->GetName().Copy( nNmLen ).ToInt32(); +/*N*/ if( nNum-- && nNum < pTblFrmFmtTbl->Count() ) +/*N*/ pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 )); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // alle Nummern entsprechend geflag, also bestimme die richtige Nummer +/*N*/ nNum = pTblFrmFmtTbl->Count(); +/*N*/ for( n = 0; n < nFlagSize; ++n ) +/*N*/ if( 0xff != ( nTmp = pSetFlags[ n ] )) +/*N*/ { +/*N*/ // also die Nummer bestimmen +/*N*/ nNum = n * 8; +/*N*/ while( nTmp & 1 ) +/*N*/ ++nNum, nTmp >>= 1; +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ delete [] pSetFlags; +/*N*/ return aName += String::CreateFromInt32( ++nNum ); +/*N*/ } + +/*N*/ SwTableFmt* SwDoc::FindTblFmtByName( const String& rName, BOOL bAll ) const +/*N*/ { +/*N*/ const SwFmt* pRet = 0; +/*N*/ if( bAll ) +/*?*/ pRet = FindFmtByName( (SvPtrarr&)*pTblFrmFmtTbl, rName ); +/*N*/ else +/*N*/ { +/*N*/ // dann nur die, die im Doc gesetzt sind +/*N*/ for( USHORT n = 0; n < pTblFrmFmtTbl->Count(); ++n ) +/*N*/ { +/*N*/ const SwFrmFmt* pFmt = (*pTblFrmFmtTbl)[ n ]; +/*N*/ if( !pFmt->IsDefault() && IsUsed( *pFmt ) && +/*N*/ pFmt->GetName() == rName ) +/*N*/ { +/*?*/ pRet = pFmt; +/*?*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return (SwTableFmt*)pRet; +/*N*/ } + + + + + +/*N*/ void SwDoc::ClearBoxNumAttrs( const SwNodeIndex& rNode ) +/*N*/ { +/*N*/ SwStartNode* pSttNd; +/*N*/ if( 0 != ( pSttNd = GetNodes()[ rNode ]-> +/*N*/ FindSttNodeByType( SwTableBoxStartNode )) && +/*N*/ 2 == pSttNd->EndOfSectionIndex() - pSttNd->GetIndex() ) +/*N*/ { +/*N*/ SwTableBox* pBox = pSttNd->FindTableNode()->GetTable(). +/*N*/ GetTblBox( pSttNd->GetIndex() ); +/*N*/ +/*N*/ const SfxPoolItem* pFmtItem = 0; +/*N*/ const SfxItemSet& rSet = pBox->GetFrmFmt()->GetAttrSet(); +/*N*/ if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMAT, FALSE, &pFmtItem ) || +/*N*/ SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMULA, FALSE ) || +/*N*/ SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_VALUE, FALSE )) +/*N*/ { +/*?*/ SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt(); +/*?*/ +/*?*/ //JP 01.09.97: TextFormate bleiben erhalten! +/*?*/ USHORT nWhich1 = RES_BOXATR_FORMAT; +/*?*/ if( pFmtItem && GetNumberFormatter()->IsTextFormat( +/*?*/ ((SwTblBoxNumFormat*)pFmtItem)->GetValue() )) +/*?*/ nWhich1 = RES_BOXATR_FORMULA; +/*?*/ else +/*?*/ // JP 15.01.99: Nur Attribute zuruecksetzen reicht nicht. +/*?*/ // Sorge dafuer, das der Text auch entsprechend +/*?*/ // formatiert wird! +/*?*/ pBoxFmt->SetAttr( *GetDfltAttr( RES_BOXATR_FORMAT )); +/*?*/ +/*?*/ pBoxFmt->ResetAttr( nWhich1, RES_BOXATR_VALUE ); +/*?*/ SetModified(); +/*N*/ } +/*N*/ } +/*N*/ } + + + +// kopiert eine Tabelle aus dem selben oder einem anderen Doc in sich +// selbst. Dabei wird eine neue Tabelle angelegt oder eine bestehende +// mit dem Inhalt gefuellt; wobei entweder der Inhalt ab einer Box oder +// in eine bestehende TblSelektion gefuellt wird. +// Gerufen wird es von: edglss.cxx/fecopy.cxx + + + + + + + + + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_ndtbl1.cxx b/binfilter/bf_sw/source/core/docnode/sw_ndtbl1.cxx new file mode 100644 index 000000000000..8e9bd7c03747 --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_ndtbl1.cxx @@ -0,0 +1,407 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER +#ifdef WTC +#define private public +#endif + +#include "hintids.hxx" + +#include <bf_svx/boxitem.hxx> + +#include <horiornt.hxx> + +#include <fmtornt.hxx> +#include <frmatr.hxx> +#include <cellfrm.hxx> +#include <tabfrm.hxx> +#include <txtfrm.hxx> + +#include "doc.hxx" +#include "viscrs.hxx" +#include "swtblfmt.hxx" +namespace binfilter { + + +extern void ClearFEShellTabCols(); + +//siehe auch swtable.cxx +#define COLFUZZY 20L + + + + + + + +/*N*/ void lcl_GetStartEndCell( const SwCursor& rCrsr, +/*N*/ SwLayoutFrm *&prStart, SwLayoutFrm *&prEnd ) +/*N*/ { +/*N*/ ASSERT( rCrsr.GetCntntNode() && rCrsr.GetCntntNode( FALSE ), +/*N*/ "Tabselection nicht auf Cnt." ); +/*N*/ +/*N*/ Point aPtPos, aMkPos; +/*N*/ const SwShellCrsr* pShCrsr = rCrsr; +/*N*/ if( pShCrsr ) +/*N*/ { +/*N*/ aPtPos = pShCrsr->GetPtPos(); +/*N*/ aMkPos = pShCrsr->GetMkPos(); +/*N*/ } +/*N*/ +/*N*/ prStart = rCrsr.GetCntntNode()->GetFrm( &aPtPos )->GetUpper(); +/*N*/ prEnd = rCrsr.GetCntntNode(FALSE)->GetFrm( &aMkPos )->GetUpper(); +/*N*/ } + +/*********************************************************************** +#* Class : SwDoc +#* Methoden : SetRowHeight(), GetRowHeight() +#* Datum : MA 17. May. 93 +#* Update : JP 28.04.98 +#***********************************************************************/ +//Die Zeilenhoehe wird ausgehend von der Selektion ermittelt/gesetzt. +//Ausgehend von jeder Zelle innerhalb der Selektion werden nach oben alle +//Zeilen abgeklappert, die oberste Zeile erhaelt den gewuenschten Wert alle +//tieferliegenden Zeilen einen entsprechenden Wert der sich aus der +//Relation der alten und neuen Groesse der obersten Zeile und ihrer +//eigenen Groesse ergiebt. +//Alle veraenderten Zeilen erhalten ggf. ein eigenes FrmFmt. +//Natuerlich darf jede Zeile nur einmal angefasst werden. + +/*N*/ inline void InsertLine( SvPtrarr& rLineArr, SwTableLine* pLine ) +/*N*/ { +/*N*/ if( USHRT_MAX == rLineArr.GetPos( (void*&)pLine ) ) +/*N*/ rLineArr.Insert( (void*&)pLine, rLineArr.Count() ); +/*N*/ } + +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + +/*N*/ struct LinesAndTable +/*N*/ { +/*N*/ SvPtrarr &rLines; +/*N*/ const SwTable &rTable; +/*N*/ BOOL bInsertLines; +/*N*/ +/*N*/ LinesAndTable( SvPtrarr &rL, const SwTable &rTbl ) : +/*N*/ rLines( rL ), rTable( rTbl ), bInsertLines( TRUE ) {} +/*N*/ }; + + +/*N*/ BOOL _FindLine( const _FndLine*& rpLine, void* pPara ); + +/*N*/ BOOL _FindBox( const _FndBox*& rpBox, void* pPara ) +/*N*/ { +/*N*/ if ( rpBox->GetLines().Count() ) +/*N*/ { +/*N*/ ((LinesAndTable*)pPara)->bInsertLines = TRUE; +/*N*/ ((_FndBox*)rpBox)->GetLines().ForEach( _FindLine, pPara ); +/*N*/ if ( ((LinesAndTable*)pPara)->bInsertLines ) +/*N*/ { +/*N*/ const SwTableLines &rLines = rpBox->GetBox() +/*N*/ ? rpBox->GetBox()->GetTabLines() +/*N*/ : ((LinesAndTable*)pPara)->rTable.GetTabLines(); +/*N*/ if ( rpBox->GetLines().Count() == rLines.Count() ) +/*N*/ { +/*N*/ for ( USHORT i = 0; i < rLines.Count(); ++i ) +/*N*/ ::binfilter::InsertLine( ((LinesAndTable*)pPara)->rLines, +/*N*/ (SwTableLine*)rLines[i] ); +/*N*/ } +/*N*/ else +/*N*/ ((LinesAndTable*)pPara)->bInsertLines = FALSE; +/*N*/ } +/*N*/ } +/*N*/ else if ( rpBox->GetBox() ) +/*N*/ ::binfilter::InsertLine( ((LinesAndTable*)pPara)->rLines, +/*N*/ (SwTableLine*)rpBox->GetBox()->GetUpper() ); +/*N*/ return TRUE; +/*N*/ } + +/*N*/ BOOL _FindLine( const _FndLine*& rpLine, void* pPara ) +/*N*/ { +/*N*/ ((_FndLine*)rpLine)->GetBoxes().ForEach( _FindBox, pPara ); +/*N*/ return TRUE; +/*N*/ } + + +/*********************************************************************** +#* Class : SwDoc +#* Methoden : SetTabBorders(), GetTabBorders() +#* Datum : MA 18. May. 93 +#* Update : JP 29.04.98 +#***********************************************************************/ +/*N*/ inline void InsertCell( SvPtrarr& rCellArr, SwCellFrm* pCellFrm ) +/*N*/ { +/*N*/ if( USHRT_MAX == rCellArr.GetPos( (void*&)pCellFrm ) ) +/*N*/ rCellArr.Insert( (void*&)pCellFrm, rCellArr.Count() ); +/*N*/ } + +//----------------------------------------------------------------------------- +/*N*/ void lcl_CollectCells( SvPtrarr &rArr, const SwRect &rUnion, +/*N*/ SwTabFrm *pTab ) +/*N*/ { +/*N*/ SwLayoutFrm *pCell = pTab->FirstCell(); +/*N*/ do +/*N*/ { +/*N*/ // Wenn in der Zelle ein spaltiger Bereich sitzt, muessen wir +/*N*/ // uns erst wieder zur Zelle hochhangeln +/*N*/ while ( !pCell->IsCellFrm() ) +/*?*/ pCell = pCell->GetUpper(); +/*N*/ ASSERT( pCell, "Frame ist keine Zelle." ); +/*N*/ if ( rUnion.IsOver( pCell->Frm() ) ) +/*N*/ ::binfilter::InsertCell( rArr, (SwCellFrm*)pCell ); +/*N*/ //Dafuer sorgen, dass die Zelle auch verlassen wird (Bereiche) +/*N*/ SwLayoutFrm *pTmp = pCell; +/*N*/ do +/*N*/ { pTmp = pTmp->GetNextLayoutLeaf(); +/*N*/ } while ( pCell->IsAnLower( pTmp ) ); +/*N*/ pCell = pTmp; +/*N*/ } while( pCell && pTab->IsAnLower( pCell ) ); +/*N*/ } + + + + +/*N*/ void SwDoc::GetTabBorders( const SwCursor& rCursor, SfxItemSet& rSet ) const +/*N*/ { +/*N*/ SwTableNode* pTblNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode(); +/*N*/ if( !pTblNd ) +/*?*/ return ; +/*N*/ +/*N*/ SwLayoutFrm *pStart, *pEnd; +/*N*/ ::binfilter::lcl_GetStartEndCell( rCursor, pStart, pEnd ); +/*N*/ +/*N*/ SwSelUnions aUnions; +/*N*/ ::binfilter::MakeSelUnions( aUnions, pStart, pEnd ); +/*N*/ +/*N*/ if( aUnions.Count() ) +/*N*/ { +/*N*/ SvxBoxItem aSetBox ((const SvxBoxItem &) rSet.Get(RES_BOX )); +/*N*/ SvxBoxInfoItem aSetBoxInfo((const SvxBoxInfoItem&) rSet.Get(SID_ATTR_BORDER_INNER)); +/*N*/ +/*N*/ BOOL bTopSet = FALSE, +/*N*/ bBottomSet = FALSE, +/*N*/ bLeftSet = FALSE, +/*N*/ bRightSet = FALSE, +/*N*/ bHoriSet = FALSE, +/*N*/ bVertSet = FALSE, +/*N*/ bDistanceSet = FALSE; +/*N*/ +/*N*/ aSetBoxInfo.ResetFlags(); +/*N*/ +/*N*/ for ( USHORT i = 0; i < aUnions.Count(); ++i ) +/*N*/ { +/*N*/ SwSelUnion *pUnion = aUnions[i]; +/*N*/ const SwTabFrm *pTab = pUnion->GetTable(); +/*N*/ const SwRect &rUnion = pUnion->GetUnion(); +/*N*/ const BOOL bFirst = i == 0 ? TRUE : FALSE; +/*N*/ const BOOL bLast = i == aUnions.Count() - 1 ? TRUE : FALSE; +/*N*/ +/*N*/ SvPtrarr aCellArr( 255, 255 ); +/*N*/ ::binfilter::lcl_CollectCells( aCellArr, rUnion, (SwTabFrm*)pTab ); +/*N*/ +/*N*/ for ( USHORT j = 0; j < aCellArr.Count(); ++j ) +/*N*/ { +/*N*/ const SwCellFrm *pCell = (const SwCellFrm*)aCellArr[j]; +/*N*/ const sal_Bool bVert = pCell->IsVertical(); +/*N*/ const sal_Bool bRTL = pCell->IsRightToLeft(); +/*N*/ sal_Bool bTopOver, bLeftOver, bRightOver, bBottomOver; +/*N*/ if ( bVert ) +/*N*/ { +/*N*/ bTopOver = pCell->Frm().Right() >= rUnion.Right(); +/*N*/ bLeftOver = pCell->Frm().Top() <= rUnion.Top(); +/*N*/ bRightOver = pCell->Frm().Bottom() >= rUnion.Bottom(); +/*N*/ bBottomOver = pCell->Frm().Left() <= rUnion.Left(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bTopOver = pCell->Frm().Top() <= rUnion.Top(); +/*N*/ bLeftOver = pCell->Frm().Left() <= rUnion.Left(); +/*N*/ bRightOver = pCell->Frm().Right() >= rUnion.Right(); +/*N*/ bBottomOver = pCell->Frm().Bottom() >= rUnion.Bottom(); +/*N*/ } +/*N*/ +/*N*/ if ( bRTL ) +/*N*/ { +/*N*/ sal_Bool bTmp = bRightOver; +/*N*/ bRightOver = bLeftOver; +/*N*/ bLeftOver = bTmp; +/*N*/ } +/*N*/ +/*N*/ const SwFrmFmt *pFmt = pCell->GetFmt(); +/*N*/ const SvxBoxItem &rBox = pFmt->GetBox(); +/*N*/ +/*N*/ //Obere Kante +/*N*/ if ( bFirst && bTopOver ) +/*N*/ { +/*N*/ if (aSetBoxInfo.IsValid(VALID_TOP)) +/*N*/ { +/*N*/ if ( !bTopSet ) +/*N*/ { bTopSet = TRUE; +/*N*/ aSetBox.SetLine( rBox.GetTop(), BOX_LINE_TOP ); +/*N*/ } +/*?*/ else if ((aSetBox.GetTop() && rBox.GetTop() && +/*?*/ !(*aSetBox.GetTop() == *rBox.GetTop())) || +/*?*/ ((!aSetBox.GetTop()) ^ (!rBox.GetTop()))) // XOR-Ausdruck ist TRUE, wenn genau einer der beiden Pointer 0 ist +/*?*/ { +/*?*/ aSetBoxInfo.SetValid(VALID_TOP, FALSE ); +/*?*/ aSetBox.SetLine( 0, BOX_LINE_TOP ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Linke Kante +/*N*/ if ( bLeftOver ) +/*N*/ { +/*N*/ if (aSetBoxInfo.IsValid(VALID_LEFT)) +/*N*/ { +/*N*/ if ( !bLeftSet ) +/*N*/ { bLeftSet = TRUE; +/*N*/ aSetBox.SetLine( rBox.GetLeft(), BOX_LINE_LEFT ); +/*N*/ } +/*N*/ else if ((aSetBox.GetLeft() && rBox.GetLeft() && +/*?*/ !(*aSetBox.GetLeft() == *rBox.GetLeft())) || +/*?*/ ((!aSetBox.GetLeft()) ^ (!rBox.GetLeft()))) +/*?*/ { +/*?*/ aSetBoxInfo.SetValid(VALID_LEFT, FALSE ); +/*?*/ aSetBox.SetLine( 0, BOX_LINE_LEFT ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ if (aSetBoxInfo.IsValid(VALID_VERT)) +/*?*/ { +/*?*/ if ( !bVertSet ) +/*?*/ { bVertSet = TRUE; +/*?*/ aSetBoxInfo.SetLine( rBox.GetLeft(), BOXINFO_LINE_VERT ); +/*?*/ } +/*?*/ else if ((aSetBoxInfo.GetVert() && rBox.GetLeft() && +/*?*/ !(*aSetBoxInfo.GetVert() == *rBox.GetLeft())) || +/*?*/ ((!aSetBoxInfo.GetVert()) ^ (!rBox.GetLeft()))) +/*?*/ { aSetBoxInfo.SetValid( VALID_VERT, FALSE ); +/*?*/ aSetBoxInfo.SetLine( 0, BOXINFO_LINE_VERT ); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ //Rechte Kante +/*N*/ if ( aSetBoxInfo.IsValid(VALID_RIGHT) && bRightOver ) +/*N*/ { +/*N*/ if ( !bRightSet ) +/*N*/ { bRightSet = TRUE; +/*N*/ aSetBox.SetLine( rBox.GetRight(), BOX_LINE_RIGHT ); +/*N*/ } +/*N*/ else if ((aSetBox.GetRight() && rBox.GetRight() && +/*?*/ !(*aSetBox.GetRight() == *rBox.GetRight())) || +/*?*/ (!aSetBox.GetRight() ^ !rBox.GetRight())) +/*?*/ { aSetBoxInfo.SetValid( VALID_RIGHT, FALSE ); +/*?*/ aSetBox.SetLine( 0, BOX_LINE_RIGHT ); +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ //Untere Kante +/*N*/ if ( bLast && bBottomOver ) +/*N*/ { +/*N*/ if ( aSetBoxInfo.IsValid(VALID_BOTTOM) ) +/*N*/ { +/*N*/ if ( !bBottomSet ) +/*N*/ { bBottomSet = TRUE; +/*N*/ aSetBox.SetLine( rBox.GetBottom(), BOX_LINE_BOTTOM ); +/*N*/ } +/*N*/ else if ((aSetBox.GetBottom() && rBox.GetBottom() && +/*?*/ !(*aSetBox.GetBottom() == *rBox.GetBottom())) || +/*?*/ (!aSetBox.GetBottom() ^ !rBox.GetBottom())) +/*?*/ { aSetBoxInfo.SetValid( VALID_BOTTOM, FALSE ); +/*?*/ aSetBox.SetLine( 0, BOX_LINE_BOTTOM ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ //in allen Zeilen ausser der letzten werden die +/*N*/ // horiz. Linien aus der Bottom-Linie entnommen +/*N*/ else +/*N*/ { +/*?*/ if (aSetBoxInfo.IsValid(VALID_HORI)) +/*?*/ { +/*?*/ if ( !bHoriSet ) +/*?*/ { bHoriSet = TRUE; +/*?*/ aSetBoxInfo.SetLine( rBox.GetBottom(), BOXINFO_LINE_HORI ); +/*?*/ } +/*?*/ else if ((aSetBoxInfo.GetHori() && rBox.GetBottom() && +/*?*/ !(*aSetBoxInfo.GetHori() == *rBox.GetBottom())) || +/*?*/ ((!aSetBoxInfo.GetHori()) ^ (!rBox.GetBottom()))) +/*?*/ { +/*?*/ aSetBoxInfo.SetValid( VALID_HORI, FALSE ); +/*?*/ aSetBoxInfo.SetLine( 0, BOXINFO_LINE_HORI ); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ // Abstand zum Text +/*N*/ if (aSetBoxInfo.IsValid(VALID_DISTANCE)) +/*N*/ { +/*N*/ static USHORT __READONLY_DATA aBorders[] = { +/*N*/ BOX_LINE_BOTTOM, BOX_LINE_TOP, +/*N*/ BOX_LINE_RIGHT, BOX_LINE_LEFT }; +/*N*/ const USHORT* pBrd = aBorders; +/*N*/ +/*N*/ if( !bDistanceSet ) // bei 1. Durchlauf erstmal setzen +/*N*/ { +/*N*/ bDistanceSet = TRUE; +/*N*/ for( int i = 0; i < 4; ++i, ++pBrd ) +/*N*/ aSetBox.SetDistance( rBox.GetDistance( *pBrd ), +/*N*/ *pBrd ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ for( int i = 0; i < 4; ++i, ++pBrd ) +/*?*/ if( aSetBox.GetDistance( *pBrd ) != +/*?*/ rBox.GetDistance( *pBrd ) ) +/*?*/ { +/*?*/ aSetBoxInfo.SetValid( VALID_DISTANCE, FALSE ); +/*?*/ aSetBox.SetDistance( (USHORT) 0 ); +/*?*/ break; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ rSet.Put( aSetBox ); +/*N*/ rSet.Put( aSetBoxInfo ); +/*N*/ } +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_node.cxx b/binfilter/bf_sw/source/core/docnode/sw_node.cxx new file mode 100644 index 000000000000..b25a262f0ded --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_node.cxx @@ -0,0 +1,1351 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <bf_svx/protitem.hxx> +#include <com/sun/star/i18n/CharacterIteratorMode.hdl> + +#include <fmtanchr.hxx> +#include <txtftn.hxx> +#include <ftnfrm.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <docary.hxx> +#include <swtable.hxx> +#include <ndtxt.hxx> +#include <pam.hxx> +#include <section.hxx> +#include <flyfrm.hxx> +#include <txtfrm.hxx> +#include <paratr.hxx> +#include <ftnidx.hxx> +#include <fmtftn.hxx> +#include <fmtcntnt.hxx> +#include <frmtool.hxx> +#include <pagefrm.hxx> +#include <node2lay.hxx> +#include <hints.hxx> +#include <breakit.hxx> +#include <crsskip.hxx> +#include <SwStyleNameMapper.hxx> +namespace binfilter { +using namespace ::com::sun::star::i18n; + +/*N*/ TYPEINIT2( SwCntntNode, SwModify, SwIndexReg ) + +/******************************************************************* +|* +|* 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 !! +|* +*******************************************************************/ + + + +/******************************************************************* +|* +|* 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 +|* +*******************************************************************/ + + +/*N*/ SwNode::SwNode( const SwNodeIndex &rWhere, const BYTE nNdType ) +/*N*/ : pStartOfSection( 0 ), nNodeType( nNdType ) +/*N*/ { +/*N*/ bWrongDirty = bACmplWrdDirty = TRUE; +/*N*/ bSetNumLSpace = bIgnoreDontExpand = FALSE; +/*N*/ nAFmtNumLvl = 0; +/*N*/ +/*N*/ SwNodes& rNodes = (SwNodes&)rWhere.GetNodes(); +/*N*/ SwNode* pInsNd = this; // der MAC kann this nicht einfuegen !! +/*N*/ if( rWhere.GetIndex() ) +/*N*/ { +/*N*/ SwNode* pNd = rNodes[ rWhere.GetIndex() -1 ]; +/*N*/ rNodes.Insert( pInsNd, rWhere ); +/*N*/ if( 0 == ( pStartOfSection = pNd->GetStartNode()) ) +/*N*/ { +/*N*/ pStartOfSection = pNd->pStartOfSection; +/*N*/ if( pNd->GetEndNode() ) // EndNode ? Section ueberspringen! +/*N*/ { +/*N*/ pNd = pStartOfSection; +/*N*/ pStartOfSection = pNd->pStartOfSection; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ rNodes.Insert( pInsNd, rWhere ); +/*?*/ pStartOfSection = (SwStartNode*)this; +/*N*/ } +/*N*/ } + +/*N*/ SwNode::SwNode( SwNodes& rNodes, ULONG nPos, const BYTE nNdType ) +/*N*/ : pStartOfSection( 0 ), nNodeType( nNdType ) +/*N*/ { +/*N*/ bWrongDirty = bACmplWrdDirty = TRUE; +/*N*/ bSetNumLSpace = bIgnoreDontExpand = FALSE; +/*N*/ nAFmtNumLvl = 0; +/*N*/ +/*N*/ SwNode* pInsNd = this; // der MAC kann this nicht einfuegen !! +/*N*/ if( nPos ) +/*N*/ { +/*N*/ SwNode* pNd = rNodes[ nPos - 1 ]; +/*N*/ rNodes.Insert( pInsNd, nPos ); +/*N*/ if( 0 == ( pStartOfSection = pNd->GetStartNode()) ) +/*N*/ { +/*N*/ pStartOfSection = pNd->pStartOfSection; +/*N*/ if( pNd->GetEndNode() ) // EndNode ? Section ueberspringen! +/*N*/ { +/*N*/ pNd = pStartOfSection; +/*N*/ pStartOfSection = pNd->pStartOfSection; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ rNodes.Insert( pInsNd, nPos ); +/*N*/ pStartOfSection = (SwStartNode*)this; +/*N*/ } +/*N*/ } + +/*N*/ SwNode::~SwNode() +/*N*/ { +/*N*/ } + +// suche den TabellenNode, in dem dieser steht. Wenn in keiner +// Tabelle wird 0 returnt. + + +/*N*/ SwTableNode* SwNode::FindTableNode() +/*N*/ { +/*N*/ if( IsTableNode() ) +/*N*/ return GetTableNode(); +/*N*/ SwStartNode* pTmp = pStartOfSection; +/*N*/ while( !pTmp->IsTableNode() && pTmp->GetIndex() ) +/*N*/ #if defined( ALPHA ) && defined( UNX ) +/*?*/ pTmp = ((SwNode*)pTmp)->pStartOfSection; +/*N*/ #else +/*N*/ pTmp = pTmp->pStartOfSection; +/*N*/ #endif +/*N*/ return pTmp->GetTableNode(); +/*N*/ } + + +// liegt der Node im Sichtbarenbereich der Shell ? + +/*N*/ BOOL SwNode::IsInProtectSect() const +/*N*/ { +/*N*/ const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this; +/*N*/ const SwSectionNode* pSectNd = pNd->FindSectionNode(); +/*N*/ return pSectNd && pSectNd->GetSection().IsProtectFlag(); +/*N*/ } + + // befindet sich der Node in irgendetwas geschuetzten ? + // (Bereich/Rahmen/Tabellenzellen/... incl. des Ankers bei + // Rahmen/Fussnoten/..) +/*N*/ BOOL SwNode::IsProtect() const +/*N*/ { +/*N*/ const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this; +/*N*/ const SwStartNode* pSttNd = pNd->FindSectionNode(); +/*N*/ if( pSttNd && ((SwSectionNode*)pSttNd)->GetSection().IsProtectFlag() ) +/*N*/ return TRUE; +/*N*/ +/*N*/ if( 0 != ( pSttNd = FindTableBoxStartNode() ) ) +/*N*/ { +/*N*/ SwCntntFrm* pCFrm; +/*N*/ if( IsCntntNode() && 0 != (pCFrm = ((SwCntntNode*)this)->GetFrm() )) +/*N*/ return pCFrm->IsProtected(); +/*N*/ +/*N*/ const SwTableBox* pBox = pSttNd->FindTableNode()->GetTable(). +/*N*/ GetTblBox( pSttNd->GetIndex() ); +/*N*/ if( pBox->GetFrmFmt()->GetProtect().IsCntntProtected() ) +/*?*/ return TRUE; +/*N*/ } +/*N*/ +/*N*/ SwFrmFmt* pFlyFmt = GetFlyFmt(); +/*N*/ if( pFlyFmt ) +/*N*/ { +/*N*/ if( pFlyFmt->GetProtect().IsCntntProtected() ) +/*?*/ return TRUE; +/*N*/ const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor(); +/*N*/ return rAnchor.GetCntntAnchor() +/*N*/ ? rAnchor.GetCntntAnchor()->nNode.GetNode().IsProtect() +/*N*/ : FALSE; +/*N*/ } +/*N*/ +/*N*/ if( 0 != ( pSttNd = FindFootnoteStartNode() ) ) +/*N*/ { +/*?*/ const SwTxtFtn* pTFtn = GetDoc()->GetFtnIdxs().SeekEntry( +/*?*/ SwNodeIndex( *pSttNd ) ); +/*?*/ if( pTFtn ) +/*?*/ return pTFtn->GetTxtNode().IsProtect(); +/*N*/ } +/*N*/ +/*N*/ return FALSE; +/*N*/ } + + // 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!! + + + // falls der Node in einem Fly steht, dann wird das entsprechende Format + // returnt +/*N*/ SwFrmFmt* SwNode::GetFlyFmt() const +/*N*/ { +/*N*/ SwFrmFmt* pRet = 0; +/*N*/ const SwNode* pSttNd = FindFlyStartNode(); +/*N*/ if( pSttNd ) +/*N*/ { +/*N*/ if( IsCntntNode() ) +/*N*/ { +/*N*/ SwClientIter aIter( *(SwCntntNode*)this ); +/*N*/ SwClient* pCli = aIter.First( TYPE( SwCntntFrm )); +/*N*/ if( pCli ) +/*N*/ pRet = ((SwCntntFrm*)pCli)->FindFlyFrm()->GetFmt(); +/*N*/ } +/*N*/ if( !pRet ) +/*N*/ { +/*N*/ // dann gibts noch harten steinigen Weg uebers Dokument: +/*N*/ const SwSpzFrmFmts& rFrmFmtTbl = *GetDoc()->GetSpzFrmFmts(); +/*N*/ for( USHORT n = 0; n < rFrmFmtTbl.Count(); ++n ) +/*N*/ { +/*N*/ SwFrmFmt* pFmt = rFrmFmtTbl[n]; +/*N*/ const SwFmtCntnt& rCntnt = pFmt->GetCntnt(); +/*N*/ if( rCntnt.GetCntntIdx() && +/*N*/ &rCntnt.GetCntntIdx()->GetNode() == pSttNd ) +/*N*/ { +/*N*/ pRet = pFmt; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pRet; +/*N*/ } + + +/*N*/ SwTableBox* SwNode::GetTblBox() const +/*N*/ { +/*N*/ SwTableBox* pBox = 0; +/*N*/ const SwNode* pSttNd = FindTableBoxStartNode(); +/*N*/ if( pSttNd ) +/*N*/ pBox = (SwTableBox*)pSttNd->FindTableNode()->GetTable().GetTblBox( +/*N*/ pSttNd->GetIndex() ); +/*N*/ return pBox; +/*N*/ } + +/*N*/ SwStartNode* SwNode::FindSttNodeByType( SwStartNodeType eTyp ) +/*N*/ { +/*N*/ SwStartNode* pTmp = IsStartNode() ? (SwStartNode*)this : pStartOfSection; +/*N*/ +/*N*/ while( eTyp != pTmp->GetStartNodeType() && pTmp->GetIndex() ) +/*N*/ #if defined( ALPHA ) && defined( UNX ) +/*?*/ pTmp = ((SwNode*)pTmp)->pStartOfSection; +/*N*/ #else +/*N*/ pTmp = pTmp->pStartOfSection; +/*N*/ #endif +/*N*/ return eTyp == pTmp->GetStartNodeType() ? pTmp : 0; +/*N*/ } + +/*N*/ const SwTxtNode* SwNode::FindOutlineNodeOfLevel( BYTE nLvl ) const +/*N*/ { +/*N*/ const SwTxtNode* pRet = 0; +/*N*/ const SwOutlineNodes& rONds = GetNodes().GetOutLineNds(); +/*N*/ if( MAXLEVEL > nLvl && rONds.Count() ) +/*N*/ { +/*N*/ USHORT nPos; +/*N*/ SwNode* pNd = (SwNode*)this; +/*N*/ BOOL bCheckFirst = FALSE; +/*N*/ if( !rONds.Seek_Entry( pNd, &nPos )) +/*N*/ { +/*N*/ if( nPos ) +/*N*/ nPos = nPos-1; +/*N*/ else +/*?*/ bCheckFirst = TRUE; +/*N*/ } +/*N*/ +/*N*/ if( bCheckFirst ) +/*N*/ { +/*?*/ // 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->GetFrm( &aPt, 0, FALSE ), +/*?*/ * pMyFrm = pCNd ? pCNd->GetFrm( &aPt, 0, 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; +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // oder ans Feld und von dort holen !! +/*N*/ while( nPos && nLvl < ( pRet = rONds[nPos]->GetTxtNode() ) +/*N*/ ->GetTxtColl()->GetOutlineLevel() ) +/*N*/ --nPos; +/*N*/ +/*N*/ if( !nPos ) // bei 0 gesondert holen !! +/*N*/ pRet = rONds[0]->GetTxtNode(); +/*N*/ } +/*N*/ } +/*N*/ return pRet; +/*N*/ } + +// is the node the first and/or last node of a section? +// This information is used for the export filters. Our layout never have a +// distance before or after if the node is the first or last in a section. + + + +/******************************************************************* +|* +|* 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 +|* +*******************************************************************/ + + +/*N*/ SwStartNode::SwStartNode( const SwNodeIndex &rWhere, const BYTE nNdType, +/*N*/ SwStartNodeType eSttNd ) +/*N*/ : SwNode( rWhere, nNdType ), eSttNdTyp( eSttNd ) +/*N*/ { +/*N*/ // erstmal temporaer, bis der EndNode eingefuegt wird. +/*N*/ pEndOfSection = (SwEndNode*)this; +/*N*/ } + +/*N*/ SwStartNode::SwStartNode( SwNodes& rNodes, ULONG nPos ) +/*N*/ : SwNode( rNodes, nPos, ND_STARTNODE ), eSttNdTyp( SwNormalStartNode ) +/*N*/ { +/*N*/ // erstmal temporaer, bis der EndNode eingefuegt wird. +/*N*/ pEndOfSection = (SwEndNode*)this; +/*N*/ } + + +/*N*/ void SwStartNode::CheckSectionCondColl() const +/*N*/ { +/*N*/ //FEATURE::CONDCOLL +/*N*/ SwNodeIndex aIdx( *this ); +/*N*/ ULONG nEndIdx = EndOfSectionIndex(); +/*N*/ const SwNodes& rNds = GetNodes(); +/*N*/ SwCntntNode* pCNd; +/*N*/ while( 0 != ( pCNd = rNds.GoNext( &aIdx )) && pCNd->GetIndex() < nEndIdx ) +/*N*/ pCNd->ChkCondColl(); +/*N*/ //FEATURE::CONDCOLL +/*N*/ } + +/******************************************************************* +|* +|* 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 +|* +*******************************************************************/ + + +/*N*/ SwEndNode::SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd ) +/*N*/ : SwNode( rWhere, ND_ENDNODE ) +/*N*/ { +/*N*/ pStartOfSection = &rSttNd; +/*N*/ pStartOfSection->pEndOfSection = this; +/*N*/ } + +/*N*/ SwEndNode::SwEndNode( SwNodes& rNds, ULONG nPos, SwStartNode& rSttNd ) +/*N*/ : SwNode( rNds, nPos, ND_ENDNODE ) +/*N*/ { +/*N*/ pStartOfSection = &rSttNd; +/*N*/ pStartOfSection->pEndOfSection = this; +/*N*/ } + + + +// -------------------- +// SwCntntNode +// -------------------- + + +/*N*/ SwCntntNode::SwCntntNode( const SwNodeIndex &rWhere, const BYTE nNdType, +/*N*/ SwFmtColl *pColl ) +/*N*/ : SwNode( rWhere, nNdType ), +/*N*/ pAttrSet( 0 ), +/*N*/ pCondColl( 0 ), +/*N*/ SwModify( pColl ) // CrsrsShell, FrameFmt +/*N*/ #ifdef OLD_INDEX +/*N*/ ,SwIndexReg(2) +/*N*/ #endif +/*N*/ { +/*N*/ } + + +/*N*/ SwCntntNode::~SwCntntNode() +/*N*/ { +/*N*/ // Die Basisklasse SwClient vom SwFrm nimmt sich aus +/*N*/ // der Abhaengikeitsliste raus! +/*N*/ // Daher muessen alle Frames in der Abhaengigkeitsliste geloescht werden. +/*N*/ if( GetDepends() ) +/*N*/ DelFrms(); +/*N*/ +/*N*/ if( pAttrSet ) +/*N*/ delete pAttrSet; +/*N*/ if( pCondColl ) +/*?*/ delete pCondColl; +/*N*/ } + + +/*N*/ void SwCntntNode::Modify( SfxPoolItem* pOldValue, SfxPoolItem* pNewValue ) +/*N*/ { +/*N*/ USHORT nWhich = pOldValue ? pOldValue->Which() : +/*N*/ pNewValue ? pNewValue->Which() : 0 ; +/*N*/ BOOL bNumRuleSet = FALSE, bCallModify = TRUE; +/*N*/ String sNumRule, sOldNumRule; +/*N*/ const SfxPoolItem* pItem; +/*N*/ +/*N*/ switch( nWhich ) +/*N*/ { +/*N*/ case RES_OBJECTDYING : +/*N*/ { +/*?*/ SwFmt * pFmt = (SwFmt *) ((SwPtrMsgPoolItem *)pNewValue)->pObject; +/*?*/ +/*?*/ // nicht umhaengen wenn dieses das oberste Format ist !! +/*?*/ if( pRegisteredIn == pFmt ) +/*?*/ { +/*?*/ if( pFmt->GetRegisteredIn() ) +/*?*/ { +/*?*/ // wenn Parent, dann im neuen Parent wieder anmelden +/*?*/ ((SwModify*)pFmt->GetRegisteredIn())->Add( this ); +/*?*/ if ( pAttrSet ) +/*?*/ pAttrSet->SetParent( +/*?*/ &((SwFmt*)GetRegisteredIn())->GetAttrSet() ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ // sonst auf jeden Fall beim sterbenden abmelden +/*?*/ ((SwModify*)GetRegisteredIn())->Remove( this ); +/*?*/ if ( pAttrSet ) +/*?*/ pAttrSet->SetParent( 0 ); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ +/*N*/ case RES_FMT_CHG: +/*N*/ // falls mein Format Parent umgesetzt wird, dann melde ich +/*N*/ // meinen Attrset beim Neuen an. +/*N*/ +/*N*/ // sein eigenes Modify ueberspringen !! +/*N*/ if( pAttrSet && +/*N*/ ((SwFmtChg*)pNewValue)->pChangedFmt == GetRegisteredIn() ) +/*N*/ { +/*N*/ // den Set an den neuen Parent haengen +/*N*/ pAttrSet->SetParent( GetRegisteredIn() ? +/*N*/ &((SwFmt*)GetRegisteredIn())->GetAttrSet() : 0 ); +/*N*/ } +/*N*/ if( GetNodes().IsDocNodes() && IsTxtNode() ) +/*N*/ { +/*N*/ if( 0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, TRUE ))) +/*N*/ { +/*?*/ bNumRuleSet = TRUE; +/*?*/ sNumRule = ((SwNumRuleItem*)pItem)->GetValue(); +/*N*/ } +/*N*/ sOldNumRule = ((SwFmtChg*)pOldValue)->pChangedFmt->GetNumRule().GetValue(); +/*N*/ } +/*N*/ break; +/*N*/ //FEATURE::CONDCOLL +/*N*/ case RES_CONDCOLL_CONDCHG: +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( ((SwCondCollCondChg*)pNewValue)->pChangedFmt == GetRegisteredIn() && +/*?*/ return ; // nicht an die Basisklasse / Frames weitergeben +/*N*/ //FEATURE::CONDCOLL +/*N*/ +/*N*/ case RES_ATTRSET_CHG: +/*N*/ if( GetNodes().IsDocNodes() && IsTxtNode() ) +/*N*/ { +/*N*/ if( SFX_ITEM_SET == ((SwAttrSetChg*)pNewValue)->GetChgSet()->GetItemState( +/*N*/ RES_PARATR_NUMRULE, FALSE, &pItem )) +/*N*/ { +/*N*/ bNumRuleSet = TRUE; +/*N*/ sNumRule = ((SwNumRuleItem*)pItem)->GetValue(); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == ((SwAttrSetChg*)pOldValue)->GetChgSet()->GetItemState( +/*N*/ RES_PARATR_NUMRULE, FALSE, &pItem )) +/*N*/ sOldNumRule = ((SwNumRuleItem*)pItem)->GetValue(); +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_PARATR_NUMRULE: +/*?*/ if( GetNodes().IsDocNodes() && IsTxtNode() ) +/*?*/ { +/*?*/ if( pNewValue ) +/*?*/ { +/*?*/ bNumRuleSet = TRUE; +/*?*/ sNumRule = ((SwNumRuleItem*)pNewValue)->GetValue(); +/*?*/ } +/*?*/ if( pOldValue ) +/*?*/ sOldNumRule = ((SwNumRuleItem*)pOldValue)->GetValue(); +/*?*/ } +/*?*/ break; +/*?*/ } +/*N*/ +/*N*/ if( bNumRuleSet ) +/*N*/ { +/*N*/ if( sNumRule.Len() ) +/*N*/ { +/*N*/ if( !((SwTxtNode*)this)->GetNum() ) +/*N*/ ((SwTxtNode*)this)->UpdateNum( SwNodeNum(0) ); +/*N*/ #ifndef NUM_RELSPACE +/*N*/ SetNumLSpace( TRUE ); +/*N*/ #endif +/*N*/ SwNumRule* pRule = GetDoc()->FindNumRulePtr( sNumRule ); +/*N*/ if( !pRule ) +/*N*/ { +/*?*/ USHORT nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( sNumRule, GET_POOLID_NUMRULE ); +/*?*/ if( USHRT_MAX != nPoolId ) +/*?*/ pRule = GetDoc()->GetNumRuleFromPool( nPoolId ); +/*N*/ } +/*N*/ if( pRule ) +/*N*/ pRule->SetInvalidRule( TRUE ); +/*N*/ } +/*N*/ else if( ((SwTxtNode*)this)->GetNum() ) +/*N*/ { +/*?*/ bCallModify = FALSE; +/*?*/ SwModify::Modify( pOldValue, pNewValue ); +/*?*/ ((SwTxtNode*)this)->UpdateNum( SwNodeNum(NO_NUMBERING) ); +/*?*/ #ifndef NUM_RELSPACE +/*?*/ SetNumLSpace( TRUE ); +/*?*/ #endif +/*N*/ } +/*N*/ } +/*N*/ if( sOldNumRule.Len() && sNumRule != sOldNumRule ) +/*N*/ { +/*?*/ SwNumRule* pRule = GetDoc()->FindNumRulePtr( sOldNumRule ); +/*?*/ if( pRule ) +/*?*/ pRule->SetInvalidRule( TRUE ); +/*N*/ } +/*N*/ +/*N*/ if( bCallModify ) +/*N*/ SwModify::Modify( pOldValue, pNewValue ); +/*N*/ } + +/*N*/ BOOL SwCntntNode::InvalidateNumRule() +/*N*/ { +/*N*/ SwNumRule* pRule = 0; +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( GetNodes().IsDocNodes() && +/*N*/ 0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, TRUE )) && +/*N*/ ((SwNumRuleItem*)pItem)->GetValue().Len() && +/*N*/ 0 != (pRule = GetDoc()->FindNumRulePtr( +/*N*/ ((SwNumRuleItem*)pItem)->GetValue() ) ) ) +/*N*/ { +/*N*/ pRule->SetInvalidRule( TRUE ); +/*N*/ } +/*N*/ return 0 != pRule; +/*N*/ } + + +/*N*/ SwCntntFrm *SwCntntNode::GetFrm( const Point* pPoint, +/*N*/ const SwPosition *pPos, +/*N*/ const BOOL bCalcFrm ) const +/*N*/ { +/*N*/ return (SwCntntFrm*) ::binfilter::GetFrmOfModify( *(SwModify*)this, FRM_CNTNT, +/*N*/ pPoint, pPos, bCalcFrm ); +/*N*/ } + + + +/*N*/ xub_StrLen SwCntntNode::Len() const { return 0; } + + + +/*N*/ SwFmtColl *SwCntntNode::ChgFmtColl( SwFmtColl *pNewColl ) +/*N*/ { +/*N*/ ASSERT( pNewColl, Collectionpointer ist 0. ); +/*N*/ SwFmtColl *pOldColl = GetFmtColl(); +/*N*/ if( pNewColl != pOldColl ) +/*N*/ { +/*N*/ pNewColl->Add( this ); +/*N*/ +/*N*/ // setze den Parent von unseren Auto-Attributen auf die neue +/*N*/ // Collection: +/*N*/ if( pAttrSet ) +/*?*/ pAttrSet->SetParent( &pNewColl->GetAttrSet() ); +/*N*/ +/*N*/ //FEATURE::CONDCOLL +/*N*/ // HACK: hier muss die entsprechend der neuen Vorlage die Bedingungen +/*N*/ // neu ueberprueft werden! +/*N*/ if( TRUE /*pNewColl */ ) +/*N*/ { +/*N*/ SetCondFmtColl( 0 ); +/*N*/ } +/*N*/ //FEATURE::CONDCOLL +/*N*/ +/*N*/ if( !IsModifyLocked() ) +/*N*/ { +/*N*/ SwFmtChg aTmp1( pOldColl ); +/*N*/ SwFmtChg aTmp2( pNewColl ); +/*N*/ // SwModify::Modify( &aTmp1, &aTmp2 ); +/*N*/ // damit alles was im Modify passiert hier nicht noch impl. +/*N*/ // werden muss +/*N*/ SwCntntNode::Modify( &aTmp1, &aTmp2 ); +/*N*/ } +/*N*/ } +/*N*/ if ( IsInCache() ) +/*N*/ { +/*?*/ SwFrm::GetCache().Delete( this ); +/*?*/ SetInCache( FALSE ); +/*N*/ } +/*N*/ return pOldColl; +/*N*/ } + + +/*N*/ BOOL SwCntntNode::GoNext(SwIndex * pIdx, USHORT nMode ) const +/*N*/ { +/*N*/ BOOL bRet = TRUE; +/*N*/ if( pIdx->GetIndex() < Len() ) +/*N*/ { +/*N*/ if( !IsTxtNode() ) +/*?*/ (*pIdx)++; +/*N*/ else +/*N*/ { +/*N*/ const SwTxtNode& rTNd = *GetTxtNode(); +/*N*/ xub_StrLen nPos = pIdx->GetIndex(); +/*N*/ if( pBreakIt->xBreak.is() ) +/*N*/ { +/*N*/ sal_Int32 nDone = 0; +/*N*/ sal_uInt16 nItrMode = CRSR_SKIP_CHARS == nMode +/*N*/ ? CharacterIteratorMode::SKIPCONTROLCHARACTER +/*N*/ : CharacterIteratorMode::SKIPCELL; +/*N*/ nPos = pBreakIt->xBreak->nextCharacters( rTNd.GetTxt(), nPos, +/*N*/ pBreakIt->GetLocale( rTNd.GetLang( nPos ) ), +/*N*/ nItrMode, 1, nDone ); +/*N*/ if( 1 == nDone ) +/*N*/ *pIdx = nPos; +/*N*/ else +/*?*/ bRet = FALSE; +/*N*/ } +/*N*/ else if( nPos < rTNd.GetTxt().Len() ) +/*?*/ (*pIdx)++; +/*N*/ else +/*?*/ bRet = FALSE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bRet = FALSE; +/*N*/ return bRet; +/*N*/ } + + +/*N*/ BOOL SwCntntNode::GoPrevious(SwIndex * pIdx, USHORT nMode ) const +/*N*/ { +/*N*/ BOOL bRet = TRUE; +/*N*/ if( pIdx->GetIndex() > 0 ) +/*N*/ { +/*N*/ if( !IsTxtNode() ) +/*?*/ (*pIdx)--; +/*N*/ else +/*N*/ { +/*N*/ const SwTxtNode& rTNd = *GetTxtNode(); +/*N*/ xub_StrLen nPos = pIdx->GetIndex(); +/*N*/ if( pBreakIt->xBreak.is() ) +/*N*/ { +/*N*/ sal_Int32 nDone = 0; +/*N*/ sal_uInt16 nItrMode = CRSR_SKIP_CHARS == nMode +/*N*/ ? CharacterIteratorMode::SKIPCONTROLCHARACTER +/*N*/ : CharacterIteratorMode::SKIPCELL; +/*N*/ nPos = pBreakIt->xBreak->previousCharacters( rTNd.GetTxt(), nPos, +/*N*/ pBreakIt->GetLocale( rTNd.GetLang( nPos ) ), +/*N*/ nItrMode, 1, nDone ); +/*N*/ if( 1 == nDone ) +/*N*/ *pIdx = nPos; +/*N*/ else +/*?*/ bRet = FALSE; +/*N*/ } +/*N*/ else if( nPos ) +/*?*/ (*pIdx)--; +/*N*/ else +/*?*/ bRet = FALSE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bRet = FALSE; +/*N*/ return bRet; +/*N*/ } + + +/* + * Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom + * Dokument. Die erzeugten Contentframes werden in das entsprechende + * Layout gehaengt. + */ + + +/*N*/ void SwCntntNode::MakeFrms( SwCntntNode& rNode ) +/*N*/ { +/*N*/ ASSERT( &rNode != this, +/*N*/ "Kein Contentnode oder Copy-Node und neuer Node identisch." ); +/*N*/ +/*N*/ if( !GetDepends() || &rNode == this ) // gibt es ueberhaupt Frames ?? +/*?*/ return; +/*N*/ +/*N*/ SwFrm *pFrm, *pNew; +/*N*/ SwLayoutFrm *pUpper; +/*N*/ // Frames anlegen fuer Nodes, die vor oder hinter der Tabelle stehen ?? +/*N*/ ASSERT( FindTableNode() == rNode.FindTableNode(), "Table confusion" ) +/*N*/ +/*N*/ SwNode2Layout aNode2Layout( *this, rNode.GetIndex() ); +/*N*/ +/*N*/ while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, rNode )) ) +/*N*/ { +/*N*/ pNew = rNode.MakeFrm(); +/*N*/ pNew->Paste( pUpper, pFrm ); +/*N*/ } +/*N*/ } + +/* + * Methode loescht fuer den Node alle Ansichten vom + * Dokument. Die Contentframes werden aus dem entsprechenden + * Layout ausgehaengt. + */ + + +/*N*/ void SwCntntNode::DelFrms() +/*N*/ { +/*N*/ if( !GetDepends() ) +/*N*/ return; +/*N*/ +/*N*/ SwClientIter aIter( *this ); +/*N*/ SwCntntFrm *pFrm; +/*N*/ +/*N*/ for( pFrm = (SwCntntFrm*)aIter.First( TYPE(SwCntntFrm)); pFrm; +/*N*/ pFrm = (SwCntntFrm*)aIter.Next() ) +/*N*/ { +/*N*/ if( pFrm->HasFollow() ) +/*N*/ pFrm->GetFollow()->_SetIsFollow( pFrm->IsFollow() ); +/*N*/ if( pFrm->IsFollow() ) +/*N*/ { +/*?*/ SwCntntFrm* pMaster = (SwTxtFrm*)pFrm->FindMaster(); +/*?*/ pMaster->SetFollow( pFrm->GetFollow() ); +/*?*/ pFrm->_SetIsFollow( FALSE ); +/*N*/ } +/*N*/ pFrm->SetFollow( 0 );//Damit er nicht auf dumme Gedanken kommt. +/*N*/ //Andernfalls kann es sein, dass ein Follow +/*N*/ //vor seinem Master zerstoert wird, der Master +/*N*/ //greift dann ueber den ungueltigen +/*N*/ //Follow-Pointer auf fremdes Memory zu. +/*N*/ //Die Kette darf hier zerknauscht werden, weil +/*N*/ //sowieso alle zerstoert werden. +/*N*/ if( pFrm->GetUpper() && pFrm->IsInFtn() && !pFrm->GetIndNext() && +/*N*/ !pFrm->GetIndPrev() ) +/*N*/ { +/*?*/ 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 ); +/*?*/ } +/*N*/ } +/*N*/ pFrm->Cut(); +/*N*/ delete pFrm; +/*N*/ } +/*N*/ if( IsTxtNode() ) +/*N*/ { +/*N*/ ((SwTxtNode*)this)->SetWrong( NULL ); +/*N*/ SetWrongDirty( TRUE ); +/*N*/ SetAutoCompleteWordDirty( TRUE ); +/*N*/ } +/*N*/ } + + + SwCntntNode *SwCntntNode::JoinNext() + { + return this; + } + + + SwCntntNode *SwCntntNode::JoinPrev() + { + return this; + } + + + + // erfrage vom Modify Informationen +/*N*/ BOOL SwCntntNode::GetInfo( SfxPoolItem& rInfo ) const +/*N*/ { +/*N*/ const SwNumRuleItem* pItem; +/*N*/ switch( rInfo.Which() ) +/*N*/ { +/*N*/ case RES_AUTOFMT_DOCNODE: +/*N*/ if( &GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes ) +/*N*/ { +/*N*/ ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = this; +/*N*/ return FALSE; +/*N*/ } +/*N*/ break; +/*?*/ case RES_GETNUMNODES: +/*?*/ if( IsTxtNode() && 0 != ( pItem = (SwNumRuleItem*)GetNoCondAttr( +/*?*/ RES_PARATR_NUMRULE, TRUE )) && +/*?*/ pItem->GetValue().Len() && +/*?*/ pItem->GetValue() == ((SwNumRuleInfo&)rInfo).GetName() && +/*?*/ GetNodes().IsDocNodes() ) +/*?*/ { +/*?*/ ((SwNumRuleInfo&)rInfo).AddNode( *(SwTxtNode*)this ); +/*?*/ } +/*?*/ return TRUE; +/*?*/ +/*?*/ case RES_GETLOWERNUMLEVEL: +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( IsTxtNode() && ((SwTxtNode*)this)->GetNum() && +/*?*/ break; +/*?*/ +/*?*/ case RES_FINDNEARESTNODE: +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( ((SwFmtPageDesc&)GetAttr( RES_PAGEDESC )).GetPageDesc() ) +/*?*/ return TRUE; +/*?*/ +/*?*/ case RES_CONTENT_VISIBLE: +/*?*/ { +/*?*/ ((SwPtrMsgPoolItem&)rInfo).pObject = +/*?*/ SwClientIter( *(SwCntntNode*)this ).First( TYPE(SwFrm) ); +/*?*/ } +/*?*/ return FALSE; +/*N*/ } +/*N*/ +/*N*/ return SwModify::GetInfo( rInfo ); +/*N*/ } + + + // setze ein Attribut +/*N*/ BOOL SwCntntNode::SetAttr(const SfxPoolItem& rAttr ) +/*N*/ { +/*N*/ if( !pAttrSet ) // lasse von den entsprechenden Nodes die +/*N*/ NewAttrSet( GetDoc()->GetAttrPool() ); // AttrSets anlegen +/*N*/ +/*N*/ ASSERT( pAttrSet, "warum wurde kein AttrSet angelegt?" ); +/*N*/ +/*N*/ if ( IsInCache() ) +/*N*/ { +/*N*/ SwFrm::GetCache().Delete( this ); +/*N*/ SetInCache( FALSE ); +/*N*/ } +/*N*/ +/*N*/ BOOL bRet = FALSE; +/*N*/ // wenn Modify gelockt ist, werden keine Modifies verschickt +/*N*/ if( IsModifyLocked() || +/*N*/ ( !GetDepends() && RES_PARATR_NUMRULE != rAttr.Which() )) +/*N*/ { +/*N*/ if( 0 != ( bRet = (0 != pAttrSet->Put( rAttr )) )) +/*N*/ // einige Sonderbehandlungen fuer Attribute +/*N*/ pAttrSet->SetModifyAtAttr( this ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwAttrSet aOld( *pAttrSet->GetPool(), pAttrSet->GetRanges() ), +/*N*/ aNew( *pAttrSet->GetPool(), pAttrSet->GetRanges() ); +/*N*/ if( 0 != ( bRet = pAttrSet->Put_BC( rAttr, &aOld, &aNew ) )) +/*N*/ { +/*N*/ // einige Sonderbehandlungen fuer Attribute +/*N*/ pAttrSet->SetModifyAtAttr( this ); +/*N*/ +/*N*/ SwAttrSetChg aChgOld( *pAttrSet, aOld ); +/*N*/ SwAttrSetChg aChgNew( *pAttrSet, aNew ); +/*N*/ Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt +/*N*/ } +/*N*/ } +/*N*/ return bRet; +/*N*/ } + + +/*N*/ BOOL SwCntntNode::SetAttr( const SfxItemSet& rSet ) +/*N*/ { +/*N*/ if( !pAttrSet ) // lasse von den entsprechenden Nodes die +/*N*/ NewAttrSet( GetDoc()->GetAttrPool() ); // AttrSets anlegen +/*N*/ +/*N*/ if ( IsInCache() ) +/*N*/ { +/*N*/ SwFrm::GetCache().Delete( this ); +/*N*/ SetInCache( FALSE ); +/*N*/ } +/*N*/ +/*N*/ BOOL bRet = FALSE; +/*N*/ +/*N*/ // wenn Modify gelockt ist, werden keine Modifies verschickt +/*N*/ if( IsModifyLocked() || ( !GetDepends() && +/*N*/ SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_NUMRULE, FALSE )) ) +/*N*/ { +/*N*/ // einige Sonderbehandlungen fuer Attribute +/*N*/ if( 0 != (bRet = (0 != pAttrSet->Put( rSet ))) ) +/*N*/ pAttrSet->SetModifyAtAttr( this ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwAttrSet aOld( *pAttrSet->GetPool(), pAttrSet->GetRanges() ), +/*N*/ aNew( *pAttrSet->GetPool(), pAttrSet->GetRanges() ); +/*N*/ if( 0 != (bRet = pAttrSet->Put_BC( rSet, &aOld, &aNew )) ) +/*N*/ { +/*N*/ // einige Sonderbehandlungen fuer Attribute +/*N*/ pAttrSet->SetModifyAtAttr( this ); +/*N*/ SwAttrSetChg aChgOld( *pAttrSet, aOld ); +/*N*/ SwAttrSetChg aChgNew( *pAttrSet, aNew ); +/*N*/ Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt +/*N*/ } +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +// Nimmt den Hint mit nWhich aus dem Delta-Array + + +/*N*/ BOOL SwCntntNode::ResetAttr( USHORT nWhich1, USHORT nWhich2 ) +/*N*/ { +/*N*/ if( !pAttrSet ) +/*?*/ return FALSE; +/*N*/ +/*N*/ if ( IsInCache() ) +/*N*/ { +/*?*/ SwFrm::GetCache().Delete( this ); +/*?*/ SetInCache( FALSE ); +/*N*/ } +/*N*/ +/*N*/ // wenn Modify gelockt ist, werden keine Modifies verschickt +/*N*/ if( IsModifyLocked() ) +/*N*/ { +/*?*/ USHORT nDel = (!nWhich2 || nWhich2 < nWhich1) +/*?*/ ? pAttrSet->ClearItem( nWhich1 ) +/*?*/ : pAttrSet->ClearItem_BC( nWhich1, nWhich2 ); +/*?*/ +/*?*/ if( !pAttrSet->Count() ) // leer, dann loeschen +/*?*/ DELETEZ( pAttrSet ); +/*?*/ return 0 != nDel; +/*N*/ } +/*N*/ +/*N*/ // sollte kein gueltiger Bereich definiert sein ? +/*N*/ if( !nWhich2 || nWhich2 < nWhich1 ) +/*N*/ nWhich2 = nWhich1; // dann setze auf 1. Id, nur dieses Item +/*N*/ +/*N*/ SwAttrSet aOld( *pAttrSet->GetPool(), pAttrSet->GetRanges() ), +/*N*/ aNew( *pAttrSet->GetPool(), pAttrSet->GetRanges() ); +/*N*/ BOOL bRet = 0 != pAttrSet->ClearItem_BC( nWhich1, nWhich2, &aOld, &aNew ); +/*N*/ +/*N*/ if( bRet ) +/*N*/ { +/*N*/ SwAttrSetChg aChgOld( *pAttrSet, aOld ); +/*N*/ SwAttrSetChg aChgNew( *pAttrSet, aNew ); +/*N*/ Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt +/*N*/ +/*N*/ if( !pAttrSet->Count() ) // leer, dann loeschen +/*N*/ DELETEZ( pAttrSet ); +/*N*/ } +/*N*/ return bRet; +/*N*/ } + + +/*N*/ USHORT SwCntntNode::ResetAllAttr() +/*N*/ { +/*N*/ if( !pAttrSet ) +/*N*/ return 0; +/*N*/ +/*N*/ if ( IsInCache() ) +/*N*/ { +/*?*/ SwFrm::GetCache().Delete( this ); +/*?*/ SetInCache( FALSE ); +/*N*/ } +/*N*/ +/*N*/ // wenn Modify gelockt ist, werden keine Modifies verschickt +/*N*/ if( IsModifyLocked() ) +/*N*/ { +/*?*/ USHORT nDel = pAttrSet->ClearItem( 0 ); +/*?*/ if( !pAttrSet->Count() ) // leer, dann loeschen +/*?*/ DELETEZ( pAttrSet ); +/*?*/ return nDel; +/*N*/ } +/*N*/ +/*N*/ SwAttrSet aOld( *pAttrSet->GetPool(), pAttrSet->GetRanges() ), +/*N*/ aNew( *pAttrSet->GetPool(), pAttrSet->GetRanges() ); +/*N*/ BOOL bRet = 0 != pAttrSet->ClearItem_BC( 0, &aOld, &aNew ); +/*N*/ +/*N*/ if( bRet ) +/*N*/ { +/*N*/ SwAttrSetChg aChgOld( *pAttrSet, aOld ); +/*N*/ SwAttrSetChg aChgNew( *pAttrSet, aNew ); +/*N*/ Modify( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt +/*N*/ +/*N*/ if( !pAttrSet->Count() ) // leer, dann loeschen +/*N*/ DELETEZ( pAttrSet ); +/*N*/ } +/*N*/ return aNew.Count(); +/*N*/ } + + +/*N*/ BOOL SwCntntNode::GetAttr( SfxItemSet& rSet, BOOL bInParent ) const +/*N*/ { +/*N*/ if( rSet.Count() ) +/*?*/ rSet.ClearItem(); +/*N*/ +/*N*/ const SwAttrSet& rAttrSet = GetSwAttrSet(); +/*N*/ if( bInParent ) +/*N*/ return rSet.Set( rAttrSet, TRUE ) ? TRUE : FALSE; +/*N*/ +/*?*/ rSet.Put( rAttrSet ); +/*?*/ return rSet.Count() ? TRUE : FALSE; +/*N*/ } + +/*N*/ const SfxPoolItem* SwCntntNode::GetNoCondAttr( USHORT nWhich, +/*N*/ BOOL bInParents ) const +/*N*/ { +/*N*/ const SfxPoolItem* pFnd = 0; +/*N*/ if( pCondColl && pCondColl->GetRegisteredIn() ) +/*N*/ { +/*?*/ if( !pAttrSet || ( SFX_ITEM_SET != pAttrSet->GetItemState( +/*?*/ nWhich, FALSE, &pFnd ) && bInParents )) +/*?*/ ((SwFmt*)GetRegisteredIn())->GetItemState( nWhich, bInParents, &pFnd ); +/*N*/ } +/*N*/ else +/*N*/ GetSwAttrSet().GetItemState( nWhich, bInParents, &pFnd ); +/*N*/ return pFnd; +/*N*/ } + + // koennen 2 Nodes zusammengefasst werden ? + // in pIdx kann die 2. Position returnt werden. +/*N*/ int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const +/*N*/ { +/*N*/ const SwNodes& rNds = GetNodes(); +/*N*/ BYTE nNdType = GetNodeType(); +/*N*/ SwNodeIndex aIdx( *this, 1 ); +/*N*/ +/*N*/ const SwNode* pNd = this; +/*N*/ while( aIdx < rNds.Count()-1 && +/*N*/ (( pNd = &aIdx.GetNode())->IsSectionNode() || +/*N*/ ( pNd->IsEndNode() && pNd->FindStartNode()->IsSectionNode() ))) +/*N*/ aIdx++; +/*N*/ +/*N*/ if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() ) +/*N*/ return FALSE; +/*N*/ if( pIdx ) +/*N*/ *pIdx = aIdx; +/*N*/ return TRUE; +/*N*/ } + + + // koennen 2 Nodes zusammengefasst werden ? + // in pIdx kann die 2. Position returnt werden. +/*N*/ int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const +/*N*/ { +/*N*/ const SwNodes& rNds = GetNodes(); +/*N*/ BYTE nNdType = GetNodeType(); +/*N*/ SwNodeIndex aIdx( *this, -1 ); +/*N*/ +/*N*/ const SwNode* pNd = this; +/*N*/ while( aIdx.GetIndex() && +/*N*/ (( pNd = &aIdx.GetNode())->IsSectionNode() || +/*N*/ ( pNd->IsEndNode() && pNd->FindStartNode()->IsSectionNode() ))) +/*?*/ aIdx--; +/*N*/ +/*N*/ if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() ) +/*?*/ return FALSE; +/*N*/ if( pIdx ) +/*N*/ *pIdx = aIdx; +/*N*/ return TRUE; +/*N*/ } + + +//FEATURE::CONDCOLL + + +/*N*/ void SwCntntNode::SetCondFmtColl( SwFmtColl* pColl ) +/*N*/ { +/*N*/ if( (!pColl && pCondColl) || ( pColl && !pCondColl ) || +/*N*/ ( pColl && pColl != pCondColl->GetRegisteredIn() ) ) +/*N*/ { +/*?*/ SwFmtColl* pOldColl = GetCondFmtColl(); +/*?*/ delete pCondColl; +/*?*/ if( pColl ) +/*?*/ pCondColl = new SwDepend( this, pColl ); +/*?*/ else +/*?*/ pCondColl = 0; +/*?*/ +/*?*/ if( pAttrSet ) +/*?*/ { +/*?*/ // Attrset beibehalten oder loeschen?? +/*?*/ // 13.04.99: Bisher wurden er geloescht, jetzt wird er beibehalten. +/*?*/ // #64637#: Beim Laden eines Dokuments wird die bedingte +/*?*/ // Vorlage nach dem Laden der harten Attribute gesetzt. Deshalb +/*?*/ // wurden die harten Attribute geloescht. +/*?*/ +/*?*/ pAttrSet->SetParent( &GetAnyFmtColl().GetAttrSet() ); +/*?*/ // steht im docfmt.cxx +/*?*/ //extern BOOL lcl_RstAttr( const SwNodePtr&, void* ); +/*?*/ // lcl_RstAttr( this, 0 ); +/*?*/ // if( pAttrSet && !pAttrSet->Count() ) +/*?*/ // delete pAttrSet, pAttrSet = 0; +/*?*/ } +/*?*/ +/*?*/ if( !IsModifyLocked() ) +/*?*/ { +/*?*/ SwFmtChg aTmp1( pOldColl ? pOldColl : GetFmtColl() ); +/*?*/ SwFmtChg aTmp2( pColl ? pColl : GetFmtColl() ); +/*?*/ SwModify::Modify( &aTmp1, &aTmp2 ); +/*?*/ } +/*?*/ if( IsInCache() ) +/*?*/ { +/*?*/ SwFrm::GetCache().Delete( this ); +/*?*/ SetInCache( FALSE ); +/*?*/ } +/*N*/ } +/*N*/ } + + +/*N*/ BOOL SwCntntNode::IsAnyCondition( SwCollCondition& rTmp ) const +/*N*/ { +/*N*/ const SwNodes& rNds = GetNodes(); +/*N*/ { +/*N*/ int nCond = 0; +/*N*/ const SwStartNode* pSttNd = FindStartNode(); +/*N*/ while( pSttNd ) +/*N*/ { +/*N*/ switch( pSttNd->GetNodeType() ) +/*N*/ { +/*?*/ case ND_TABLENODE: nCond = PARA_IN_TABLEBODY; break; +/*N*/ case ND_SECTIONNODE: nCond = PARA_IN_SECTION; break; +/*N*/ +/*N*/ default: +/*N*/ switch( pSttNd->GetStartNodeType() ) +/*N*/ { +/*N*/ case SwTableBoxStartNode: +/*N*/ { +/*N*/ nCond = PARA_IN_TABLEBODY; +/*N*/ const SwTableNode* pTblNd = pSttNd->FindTableNode(); +/*N*/ const SwTableBox* pBox; +/*N*/ if( pTblNd && 0 != ( pBox = pTblNd->GetTable(). +/*N*/ GetTblBox( pSttNd->GetIndex() ) ) && +/*N*/ pBox->IsInHeadline( &pTblNd->GetTable() ) ) +/*N*/ nCond = PARA_IN_TABLEHEAD; +/*N*/ } +/*N*/ break; +/*N*/ case SwFlyStartNode: nCond = PARA_IN_FRAME; break; +/*N*/ case SwFootnoteStartNode: +/*?*/ { +/*?*/ nCond = PARA_IN_FOOTENOTE; +/*?*/ const SwFtnIdxs& rFtnArr = rNds.GetDoc()->GetFtnIdxs(); +/*?*/ const SwTxtFtn* pTxtFtn; +/*?*/ const SwNode* pSrchNd = pSttNd; +/*?*/ +/*?*/ for( USHORT 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; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( nCond ) +/*N*/ { +/*N*/ rTmp.SetCondition( (Master_CollConditions)nCond, 0 ); +/*N*/ return TRUE; +/*N*/ } +/*N*/ pSttNd = pSttNd->GetIndex() +/*N*/ ? pSttNd->FindStartNode() +/*N*/ : 0; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ { +/*N*/ USHORT nPos; +/*N*/ const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); +/*N*/ if( rOutlNds.Count() ) +/*N*/ { +/*N*/ if( !rOutlNds.Seek_Entry( (SwCntntNode*)this, &nPos ) && nPos ) +/*N*/ --nPos; +/*N*/ if( nPos < rOutlNds.Count() && +/*N*/ rOutlNds[ nPos ]->GetIndex() < GetIndex() ) +/*N*/ { +/*N*/ SwTxtNode* pOutlNd = rOutlNds[ nPos ]->GetTxtNode(); +/*N*/ +/*N*/ if( pOutlNd->GetOutlineNum() && !pOutlNd->GetNumRule() ) +/*N*/ { +/*N*/ rTmp.SetCondition( PARA_IN_OUTLINE, +/*N*/ pOutlNd->GetOutlineNum()->GetLevel() ); +/*N*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return FALSE; +/*N*/ } + + +/*N*/ void SwCntntNode::ChkCondColl() +/*N*/ { +/*N*/ // zur Sicherheit abfragen +/*N*/ if( RES_CONDTXTFMTCOLL == GetFmtColl()->Which() ) +/*N*/ { +/*N*/ SwCollCondition aTmp( 0, 0, 0 ); +/*N*/ const SwCollCondition* pCColl; +/*N*/ +/*N*/ if( IsAnyCondition( aTmp ) && 0 != ( pCColl = +/*N*/ ((SwConditionTxtFmtColl*)GetFmtColl())->HasCondition( aTmp ))) +/*?*/ SetCondFmtColl( pCColl->GetTxtFmtColl() ); +/*N*/ else +/*N*/ { +/*N*/ if( IsTxtNode() && ((SwTxtNode*)this)->GetNumRule() && +/*N*/ ((SwTxtNode*)this)->GetNum() ) +/*N*/ { +/*N*/ // steht in einer Numerierung +/*N*/ // welcher Level? +/*N*/ aTmp.SetCondition( PARA_IN_LIST, +/*N*/ ((SwTxtNode*)this)->GetNum()->GetLevel() ); +/*N*/ pCColl = ((SwConditionTxtFmtColl*)GetFmtColl())-> +/*N*/ HasCondition( aTmp ); +/*N*/ } +/*N*/ else +/*N*/ pCColl = 0; +/*N*/ +/*N*/ if( pCColl ) +/*?*/ SetCondFmtColl( pCColl->GetTxtFmtColl() ); +/*N*/ else if( pCondColl ) +/*?*/ SetCondFmtColl( 0 ); +/*N*/ } +/*N*/ } +/*N*/ } + +//FEATURE::CONDCOLL +// Metoden aus Node.hxx - erst hier ist der TxtNode bekannt !! +// os: nur fuer ICC, da der zum optimieren zu dumm ist +/*N*/ #ifdef ICC +/*N*/ SwTxtNode *SwNode::GetTxtNode() +/*N*/ { +/*N*/ return ND_TEXTNODE == nNodeType ? (SwTxtNode*)this : 0; +/*N*/ } +/*N*/ const SwTxtNode *SwNode::GetTxtNode() const +/*N*/ { +/*N*/ return ND_TEXTNODE == nNodeType ? (const SwTxtNode*)this : 0; +/*N*/ } +/*N*/ #endif + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_node2lay.cxx b/binfilter/bf_sw/source/core/docnode/sw_node2lay.cxx new file mode 100644 index 000000000000..7f83032aa787 --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_node2lay.cxx @@ -0,0 +1,360 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <errhdl.hxx> + +#include <ndindex.hxx> +#include <swtable.hxx> +#include <ftnfrm.hxx> +#include <sectfrm.hxx> +#include "cntfrm.hxx" +#include "tabfrm.hxx" +#include "frmtool.hxx" +#include "section.hxx" +#include "node2lay.hxx" +namespace binfilter { + + +/* -----------------25.02.99 10:31------------------- + * Die SwNode2LayImpl-Klasse erledigt die eigentliche Arbeit, + * die SwNode2Layout-Klasse ist nur die der Oefffentlichkeit bekannte Schnittstelle + * --------------------------------------------------*/ +/*N*/ class SwNode2LayImpl +/*N*/ { +/*N*/ SwClientIter *pIter; // Der eigentliche Iterator +/*N*/ SvPtrarr *pUpperFrms;// Zum Einsammeln der Upper +/*N*/ ULONG nIndex; // Der Index des einzufuegenden Nodes +/*N*/ BOOL bMaster : 1; // TRUE => nur Master , FALSE => nur Frames ohne Follow +/*N*/ BOOL bInit : 1; // Ist am SwClient bereits ein First()-Aufruf erfolgt? +/*N*/ public: +/*N*/ SwNode2LayImpl( const SwNode& rNode, ULONG nIdx, BOOL bSearch ); +/*N*/ ~SwNode2LayImpl() { delete pIter; delete pUpperFrms; } +/*N*/ SwFrm* NextFrm(); // liefert den naechsten "sinnvollen" Frame +/*N*/ SwLayoutFrm* UpperFrm( SwFrm* &rpFrm, const SwNode &rNode ); +/*N*/ void SaveUpperFrms(); // Speichert (und lockt ggf.) die pUpper +/*N*/ // Fuegt unter jeden pUpper des Arrays einen Frame ein. +/*N*/ void RestoreUpperFrms( SwNodes& rNds, ULONG nStt, ULONG nEnd ); +/*N*/ +/*N*/ }; + +/* -----------------25.02.99 10:38------------------- + * Hauptaufgabe des Ctor: Das richtige SwModify zu ermitteln, + * ueber das iteriert wird. + * Uebergibt man bSearch == TRUE, so wird der naechste Cntnt- oder TableNode + * gesucht, der Frames besitzt ( zum Einsammeln der pUpper ), ansonsten wird + * erwartet, das rNode bereits auf einem solchen Cntnt- oder TableNode sitzt, + * vor oder hinter den eingefuegt werden soll. + * --------------------------------------------------*/ + +/*N*/ SwNode2LayImpl::SwNode2LayImpl( const SwNode& rNode, ULONG nIdx, BOOL bSearch ) +/*N*/ : pUpperFrms( NULL ), nIndex( nIdx ), bInit( FALSE ) +/*N*/ { +/*N*/ const SwNode* pNd = NULL; +/*N*/ if( bSearch || rNode.IsSectionNode() ) +/*N*/ { +/*N*/ // Suche den naechsten Cntnt/TblNode, der einen Frame besitzt, +/*N*/ // damit wir uns vor/hinter ihn haengen koennen +/*N*/ if( !bSearch && rNode.GetIndex() < nIndex ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwNodeIndex aTmp( *rNode.EndOfSectionNode(), +1 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwNodeIndex aTmp( rNode, -1 ); +/*N*/ pNd = rNode.GetNodes().GoNextWithFrm( &aTmp ); +/*N*/ bMaster = TRUE; +/*N*/ if( !bSearch && pNd && rNode.EndOfSectionIndex() < pNd->GetIndex() ) +/*N*/ pNd = NULL; // Nicht ueber den Bereich hinausschiessen +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pNd = &rNode; +/*N*/ bMaster = nIndex < rNode.GetIndex(); +/*N*/ } +/*N*/ if( pNd ) +/*N*/ { +/*N*/ SwModify *pMod; +/*N*/ if( pNd->IsCntntNode() ) +/*?*/ pMod = (SwModify*)pNd->GetCntntNode(); +/*N*/ else +/*N*/ { +/*?*/ ASSERT( pNd->IsTableNode(), "For Tablenodes only" ); +/*?*/ pMod = pNd->GetTableNode()->GetTable().GetFrmFmt(); +/*N*/ } +/*N*/ pIter = new SwClientIter( *pMod ); +/*N*/ } +/*N*/ else +/*N*/ pIter = NULL; +/*N*/ } + +/* -----------------25.02.99 10:41------------------- + * SwNode2LayImpl::NextFrm() liefert den naechsten "sinnvollen" Frame, + * beim ersten Aufruf wird am eigentlichen Iterator ein First gerufen, + * danach die Next-Methode. Das Ergebnis wird auf Brauchbarkeit untersucht, + * so werden keine Follows akzeptiert, ein Master wird beim Einsammeln der + * pUpper und beim Einfuegen vor ihm akzeptiert. Beim Einfuegen dahinter + * wird vom Master ausgehend der letzte Follow gesucht und zurueckgegeben. + * Wenn der Frame innerhalb eines SectionFrms liegt, wird noch festgestellt, + * ob statt des Frames der SectionFrm der geeignete Rueckgabewert ist, dies + * ist der Fall, wenn der neu einzufuegende Node ausserhalb des Bereichs liegt. + * --------------------------------------------------*/ +/*N*/ SwFrm* SwNode2LayImpl::NextFrm() +/*N*/ { +/*N*/ SwFrm* pRet; +/*N*/ if( !pIter ) +/*N*/ return FALSE; +/*N*/ if( !bInit ) +/*N*/ { +/*N*/ pRet = (SwFrm*)pIter->First(TYPE(SwFrm)); +/*N*/ bInit = TRUE; +/*N*/ } +/*N*/ else +/*N*/ pRet = (SwFrm*)pIter->Next(); +/*N*/ while( pRet ) +/*N*/ { +/*N*/ SwFlowFrm* pFlow = SwFlowFrm::CastFlowFrm( pRet ); +/*N*/ ASSERT( pFlow, "Cntnt or Table expected?!" ); +/*N*/ // Follows sind fluechtige Gestalten, deshalb werden sie ignoriert. +/*N*/ // Auch wenn wir hinter dem Frame eingefuegt werden sollen, nehmen wir +/*N*/ // zunaechst den Master, hangeln uns dann aber zum letzten Follow durch. +/*N*/ if( !pFlow->IsFollow() ) +/*N*/ { +/*N*/ if( !bMaster ) +/*N*/ { +/*N*/ while( pFlow->HasFollow() ) +/*N*/ pFlow = pFlow->GetFollow(); +/*N*/ pRet = pFlow->GetFrm(); +/*N*/ } +/*N*/ if( pRet->IsInSct() ) +/*N*/ { +/*N*/ SwSectionFrm* pSct = pRet->FindSctFrm(); +/*N*/ // Vorsicht: Wenn wir in einer Fussnote sind, so kann diese +/*N*/ // Layoutmaessig in einem spaltigen Bereich liegen, obwohl +/*N*/ // sie nodemaessig ausserhalb liegt. Deshalb muss bei Fussnoten +/*N*/ // ueberprueft werden, ob auch der SectionFrm in der Fussnote +/*N*/ // und nicht ausserhalb liegt. +/*N*/ if( !pRet->IsInFtn() || pSct->IsInFtn() ) +/*N*/ { +/*N*/ ASSERT( pSct && pSct->GetSection(), "Where's my section?" ); +/*N*/ SwSectionNode* pNd = pSct->GetSection()->GetFmt()->GetSectionNode(); +/*N*/ ASSERT( pNd, "Lost SectionNode" ); +/*N*/ // Wenn der erhaltene Frame in einem Bereichsframe steht, +/*N*/ // dessen Bereich den Ausgangsnode nicht umfasst, so kehren +/*N*/ // wir mit dem SectionFrm zurueck, sonst mit dem Cntnt/TabFrm +/*N*/ if( bMaster ) +/*N*/ { +/*N*/ if( pNd->GetIndex() >= nIndex ) +/*N*/ pRet = pSct; +/*N*/ } +/*N*/ else if( pNd->EndOfSectionIndex() < nIndex ) +/*N*/ pRet = pSct; +/*N*/ } +/*N*/ } +/*N*/ return pRet; +/*N*/ } +/*N*/ pRet = (SwFrm*)pIter->Next(); +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/*N*/ void SwNode2LayImpl::SaveUpperFrms() +/*N*/ { +/*N*/ pUpperFrms = new SvPtrarr( 0, 20 ); +/*N*/ SwFrm* pFrm; +/*N*/ while( 0 != (pFrm = NextFrm()) ) +/*N*/ { +/*N*/ SwFrm* pPrv = pFrm->GetPrev(); +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ if( pFrm ) +/*N*/ { +/*N*/ if( pFrm->IsFtnFrm() ) +/*?*/ ((SwFtnFrm*)pFrm)->ColLock(); +/*N*/ else if( pFrm->IsInSct() ) +/*?*/ pFrm->FindSctFrm()->ColLock(); +/*N*/ if( pPrv && pPrv->IsSctFrm() ) +/*N*/ ((SwSectionFrm*)pPrv)->LockJoin(); +/*N*/ pUpperFrms->Insert( (void*)pPrv, pUpperFrms->Count() ); +/*N*/ pUpperFrms->Insert( (void*)pFrm, pUpperFrms->Count() ); +/*N*/ } +/*N*/ } +/*N*/ delete pIter; +/*N*/ pIter = NULL; +/*N*/ } + +/*N*/ SwLayoutFrm* SwNode2LayImpl::UpperFrm( SwFrm* &rpFrm, const SwNode &rNode ) +/*N*/ { +/*N*/ rpFrm = NextFrm(); +/*N*/ if( !rpFrm ) +/*N*/ return NULL; +/*N*/ SwLayoutFrm* pUpper = rpFrm->GetUpper(); +/*N*/ if( rpFrm->IsSctFrm() ) +/*N*/ { +/*?*/ const SwNode* pNode = rNode.StartOfSectionNode(); +/*?*/ if( pNode->IsSectionNode() ) +/*?*/ { +/*?*/ SwFrm* pFrm = bMaster ? rpFrm->FindPrev() : rpFrm->FindNext(); +/*?*/ if( pFrm && pFrm->IsSctFrm() ) +/*?*/ { +/*?*/ if( ((SwSectionNode*)pNode)->GetSection() == +/*?*/ *((SwSectionFrm*)pFrm)->GetSection() ) +/*?*/ { +/*?*/ rpFrm = bMaster ? NULL : ((SwLayoutFrm*)pFrm)->Lower(); +/*?*/ return ((SwLayoutFrm*)pFrm); +/*?*/ } +/*?*/ pUpper = new SwSectionFrm(((SwSectionNode*)pNode)->GetSection()); +/*?*/ pUpper->Paste( rpFrm->GetUpper(), +/*?*/ bMaster ? rpFrm : rpFrm->GetNext() ); +/*?*/ static_cast<SwSectionFrm*>(pUpper)->Init(); +/*?*/ rpFrm = NULL; +/*?*/ return pUpper; +/*?*/ } +/*?*/ } +/*N*/ }; +/*N*/ if( !bMaster ) +/*N*/ rpFrm = rpFrm->GetNext(); +/*N*/ return pUpper; +/*N*/ } + +/*N*/ void SwNode2LayImpl::RestoreUpperFrms( SwNodes& rNds, ULONG nStt, ULONG nEnd ) +/*N*/ { +/*N*/ ASSERT( pUpperFrms, "RestoreUpper without SaveUpper?" ) +/*N*/ SwNode* pNd; +/*N*/ SwDoc *pDoc = rNds.GetDoc(); +/*N*/ BOOL bFirst = TRUE; +/*N*/ for( ; nStt < nEnd; ++nStt ) +/*N*/ { +/*N*/ SwFrm* pNew = 0; +/*N*/ SwFrm* pNxt; +/*N*/ SwLayoutFrm* pUp; +/*N*/ if( (pNd = rNds[nStt])->IsCntntNode() ) +/*?*/ for( USHORT n = 0; n < pUpperFrms->Count(); ) +/*?*/ { +/*?*/ pNxt = (SwFrm*)(*pUpperFrms)[n++]; +/*?*/ if( bFirst && pNxt && pNxt->IsSctFrm() ) +/*?*/ ((SwSectionFrm*)pNxt)->UnlockJoin(); +/*?*/ pUp = (SwLayoutFrm*)(*pUpperFrms)[n++]; +/*?*/ if( pNxt ) +/*?*/ pNxt = pNxt->GetNext(); +/*?*/ else +/*?*/ pNxt = pUp->Lower(); +/*?*/ pNew = ((SwCntntNode*)pNd)->MakeFrm(); +/*?*/ pNew->Paste( pUp, pNxt ); +/*?*/ (*pUpperFrms)[n-2] = pNew; +/*?*/ } +/*N*/ else if( pNd->IsTableNode() ) +/*?*/ for( USHORT x = 0; x < pUpperFrms->Count(); ) +/*?*/ { +/*?*/ pNxt = (SwFrm*)(*pUpperFrms)[x++]; +/*?*/ if( bFirst && pNxt && pNxt->IsSctFrm() ) +/*?*/ ((SwSectionFrm*)pNxt)->UnlockJoin(); +/*?*/ pUp = (SwLayoutFrm*)(*pUpperFrms)[x++]; +/*?*/ if( pNxt ) +/*?*/ pNxt = pNxt->GetNext(); +/*?*/ else +/*?*/ pNxt = pUp->Lower(); +/*?*/ pNew = ((SwTableNode*)pNd)->MakeFrm(); +/*?*/ ASSERT( pNew->IsTabFrm(), "Table exspected" ); +/*?*/ pNew->Paste( pUp, pNxt ); +/*?*/ ((SwTabFrm*)pNew)->RegistFlys(); +/*?*/ (*pUpperFrms)[x-2] = pNew; +/*?*/ } +/*N*/ else if( pNd->IsSectionNode() ) +/*N*/ { +/*N*/ nStt = pNd->EndOfSectionIndex(); +/*N*/ for( USHORT x = 0; x < pUpperFrms->Count(); ) +/*N*/ { +/*N*/ pNxt = (SwFrm*)(*pUpperFrms)[x++]; +/*N*/ if( bFirst && pNxt && pNxt->IsSctFrm() ) +/*N*/ ((SwSectionFrm*)pNxt)->UnlockJoin(); +/*N*/ pUp = (SwLayoutFrm*)(*pUpperFrms)[x++]; +/*N*/ ASSERT( pUp->GetUpper() || pUp->IsFlyFrm(), "Lost Upper" ); +/*N*/ ::binfilter::_InsertCnt( pUp, pDoc, pNd->GetIndex(), FALSE, nStt+1, pNxt ); +/*N*/ pNxt = pUp->Lower(); +/*N*/ if( pNxt ) +/*N*/ while( pNxt->GetNext() ) +/*N*/ pNxt = pNxt->GetNext(); +/*N*/ (*pUpperFrms)[x-2] = pNxt; +/*N*/ } +/*N*/ } +/*N*/ bFirst = FALSE; +/*N*/ } +/*N*/ for( USHORT x = 0; x < pUpperFrms->Count(); ++x ) +/*N*/ { +/*N*/ SwFrm* pTmp = (SwFrm*)(*pUpperFrms)[++x]; +/*N*/ if( pTmp->IsFtnFrm() ) +/*?*/ ((SwFtnFrm*)pTmp)->ColUnlock(); +/*N*/ else if( pTmp->IsInSct() ) +/*?*/ pTmp->FindSctFrm()->ColUnlock(); +/*N*/ } +/*N*/ } + + +/*N*/ SwNode2Layout::SwNode2Layout( const SwNode& rNd, ULONG nIdx ) +/*N*/ { +/*N*/ pImpl = new SwNode2LayImpl( rNd, nIdx, FALSE ); +/*N*/ } + +/*N*/ SwNode2Layout::SwNode2Layout( const SwNode& rNd ) +/*N*/ { +/*N*/ pImpl = new SwNode2LayImpl( rNd, rNd.GetIndex(), TRUE ); +/*N*/ pImpl->SaveUpperFrms(); +/*N*/ } + +/*N*/ void SwNode2Layout::RestoreUpperFrms( SwNodes& rNds, ULONG nStt, ULONG nEnd ) +/*N*/ { +/*N*/ ASSERT( pImpl, "RestoreUpperFrms without SaveUpperFrms" ); +/*N*/ pImpl->RestoreUpperFrms( rNds, nStt, nEnd ); +/*N*/ } + +/*N*/ SwFrm* SwNode2Layout::NextFrm() +/*N*/ { +/*N*/ return pImpl->NextFrm(); +/*N*/ } + +/*N*/ SwLayoutFrm* SwNode2Layout::UpperFrm( SwFrm* &rpFrm, const SwNode &rNode ) +/*N*/ { +/*N*/ return pImpl->UpperFrm( rpFrm, rNode ); +/*N*/ } + +/*N*/ SwNode2Layout::~SwNode2Layout() +/*N*/ { +/*N*/ delete pImpl; +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_nodes.cxx b/binfilter/bf_sw/source/core/docnode/sw_nodes.cxx new file mode 100644 index 000000000000..c8dc613a8b25 --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_nodes.cxx @@ -0,0 +1,1421 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <stdlib.h> + +#include <errhdl.hxx> + + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <pam.hxx> +#include <txtfld.hxx> +#include <fmtfld.hxx> +#include <hints.hxx> +#include <ndtxt.hxx> +#include <section.hxx> +#include <ddefld.hxx> +#include <swddetbl.hxx> +#include <frame.hxx> +namespace binfilter {//STRIP009 +/*N*/ extern FASTBOOL CheckNodesRange( const SwNodeIndex& rStt, +/*N*/ const SwNodeIndex& rEnd, FASTBOOL bChkSection ); + +SV_DECL_PTRARR(SwSttNdPtrs,SwStartNode*,2,2)//STRIP008 ; +} //namespace binfilter + +//#define JP_DEBUG +#ifdef JP_DEBUG +#endif +namespace binfilter { + + +// Funktion zum bestimmen des hoechsten Levels innerhalb des Bereiches + + +//----------------------------------------------------------------------- + +/******************************************************************* +|* SwNodes::SwNodes +|* +|* Beschreibung +|* Konstruktor; legt die vier Grundsektions (PostIts, +|* Inserts, Icons, Inhalt) an +*******************************************************************/ +/*N*/ SwNodes::SwNodes( SwDoc* pDocument ) +/*N*/ : pMyDoc( pDocument ), pRoot( 0 ) +/*N*/ { +/*N*/ bInNodesDel = bInDelUpdOutl = bInDelUpdNum = FALSE; +/*N*/ +/*N*/ ASSERT( pMyDoc, "in welchem Doc stehe ich denn?" ); +/*N*/ +/*N*/ ULONG nPos = 0; +/*N*/ SwStartNode* pSttNd = new SwStartNode( *this, nPos++ ); +/*N*/ pEndOfPostIts = new SwEndNode( *this, nPos++, *pSttNd ); +/*N*/ +/*N*/ SwStartNode* pTmp = new SwStartNode( *this, nPos++ ); +/*N*/ pEndOfInserts = new SwEndNode( *this, nPos++, *pTmp ); +/*N*/ +/*N*/ pTmp = new SwStartNode( *this, nPos++ ); +/*N*/ pTmp->pStartOfSection = pSttNd; +/*N*/ pEndOfAutotext = new SwEndNode( *this, nPos++, *pTmp ); +/*N*/ +/*N*/ pTmp = new SwStartNode( *this, nPos++ ); +/*N*/ pTmp->pStartOfSection = pSttNd; +/*N*/ pEndOfRedlines = new SwEndNode( *this, nPos++, *pTmp ); +/*N*/ +/*N*/ pTmp = new SwStartNode( *this, nPos++ ); +/*N*/ pTmp->pStartOfSection = pSttNd; +/*N*/ pEndOfContent = new SwEndNode( *this, nPos++, *pTmp ); +/*N*/ +/*N*/ pOutlineNds = new SwOutlineNodes; +/*N*/ } + +/******************************************************************* +|* +|* SwNodes::~SwNodes +|* +|* Beschreibung +|* dtor, loescht alle Nodes, deren Pointer in diesem dynamischen +|* Array sind. Ist kein Problem, da Nodes ausserhalb dieses +|* Arrays nicht erzeugt werden koennen und somit auch nicht +|* in mehreren drin sein koennen +|* +|* Ersterstellung +|* VER0100 vb 901214 +|* +|* Stand +|* VER0100 vb 901214 +|* +*******************************************************************/ + +/*N*/ SwNodes::~SwNodes() +/*N*/ { +/*N*/ delete pOutlineNds; +/*N*/ +/*N*/ { +/*N*/ SwNode *pNode; +/*N*/ SwNodeIndex aNdIdx( *this ); +/*N*/ while( TRUE ) +/*N*/ { +/*N*/ pNode = &aNdIdx.GetNode(); +/*N*/ if( pNode == pEndOfContent ) +/*N*/ break; +/*N*/ +/*N*/ aNdIdx++; +/*N*/ delete pNode; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // jetzt muessen alle SwNodeIndizies abgemeldet sein!!! +/*N*/ delete pEndOfContent; +/*N*/ } + +/******************************************************************* +|* +|* SwNodes::SectionDown +|* +|* Beschreibung +|* SectionDown() legt ein Paar von Start- und EndSection-Node +|* (andere Nodes koennen dazwischen liegen) an. +|* +|* Zustand des SRange beim Verlassen der Funktion: nStart ist der +|* Index des ersten Node hinter dem Start Section Node, nEnd ist +|* der Index des End Section Nodes. Beispiel: Wird Insert Section +|* mehrmals hintereinander aufgerufen, so werden mehrere +|* unmittelbar geschachtelte Sections (keine Content Nodes +|* zwischen Start- bzw. End Nodes) angelegt. +|* +|* Allg.: aRange beschreibt den Bereich -exklusive- aEnd !! +|* ( 1.Node: aStart, letzer Node: aEnd-1 !! ) +|* +|* Parameter +|* SwRange &rRange +|* IO: +|* IN +|* rRange.aStart: Einfuegeposition des StartNodes +|* rRange.aEnd: Einfuegeposition des EndNodes +|* OUT +|* rRange.aStart: steht hinter dem eingefuegten Startnode +|* rRange.aEnd: steht auf dem eingefuegen Endnode +|* +|* Ausnahmen +|* 1. SRange-Anfang und SRange-Ende muessen auf dem gleichen Level sein +|* 2. duerfen nicht auf dem obersten Level sein +|* Ist dies nicht der Fall, wird die +|* Funktion durch Aufruf von ERR_RAISE verlassen. +|* +|* Debug-Funktionen +|* die Debugging Tools geben rRange beim Eintritt und beim +|* Verlassen der Funktion aus +|* +|* Ersterstellung +|* VER0100 vb 901214 +|* +|* Stand +|* VER0100 vb 901214 +|* +*******************************************************************/ +/*N*/ void SwNodes::SectionDown(SwNodeRange *pRange, SwStartNodeType eSttNdTyp ) +/*N*/ { +/*N*/ if( pRange->aStart >= pRange->aEnd || +/*N*/ pRange->aEnd >= Count() || +/*N*/ !CheckNodesRange( pRange->aStart, pRange->aEnd )) +/*?*/ return; +/*N*/ +/*N*/ // Ist der Anfang vom Bereich vor oder auf einem EndNode, so loesche +/*N*/ // diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes enstehen. +/*N*/ // Bei anderen Nodes wird eine neuer StartNode eingefuegt +/*N*/ SwNode * pAktNode = &pRange->aStart.GetNode(); +/*N*/ SwNodeIndex aTmpIdx( *pAktNode->StartOfSectionNode() ); +/*N*/ +/*N*/ if( pAktNode->GetEndNode() ) +/*?*/ DelNodes( pRange->aStart, 1 ); // verhinder leere Section +/*N*/ else +/*N*/ { +/*N*/ // fuege einen neuen StartNode ein +/*N*/ SwNode* pSttNd = new SwStartNode( pRange->aStart, ND_STARTNODE, eSttNdTyp ); +/*N*/ pRange->aStart = *pSttNd; +/*N*/ aTmpIdx = pRange->aStart; +/*N*/ } +/*N*/ +/*N*/ // Ist das Ende vom Bereich vor oder auf einem StartNode, so loesche +/*N*/ // diesen, denn sonst wuerden leere S/E-Nodes oder E/S-Nodes enstehen +/*N*/ // Bei anderen Nodes wird eine neuer EndNode eingefuegt +/*N*/ pRange->aEnd--; +/*N*/ if( pRange->aEnd.GetNode().GetStartNode() ) +/*?*/ DelNodes( pRange->aEnd, 1 ); +/*N*/ else +/*N*/ { +/*N*/ pRange->aEnd++; +/*N*/ // fuege einen neuen EndNode ein +/*N*/ new SwEndNode( pRange->aEnd, *pRange->aStart.GetNode().GetStartNode() ); +/*N*/ } +/*N*/ pRange->aEnd--; +/*N*/ +/*N*/ SectionUpDown( aTmpIdx, pRange->aEnd ); +/*N*/ } + +/******************************************************************* +|* +|* SwNodes::SectionUp +|* +|* Beschreibung +|* Der von rRange umspannte Bereich wird auf die naechst hoehere +|* Ebene gehoben. Das geschieht dadurch, dass bei +|* rRange.aStart ein Endnode und bei rRange.aEnd ein +|* Startnode eingefuegt wird. Die Indices fuer den Bereich +|* innerhalb von rRange werden geupdated. +|* +|* Allg.: aRange beschreibt den Bereich -exklusive- aEnd !! +|* ( 1.Node: aStart, letzer Node: aEnd-1 !! ) +|* +|* Parameter +|* SwRange &rRange +|* IO: +|* IN +|* rRange.aStart: Anfang des hoeher zubewegenden Bereiches +|* rRange.aEnd: der 1.Node hinter dem Bereich +|* OUT +|* rRange.aStart: an der ersten Position innerhalb des +|* hochbewegten Bereiches +|* rRange.aEnd: an der letzten Position innerhalb des +|* hochbewegten Bereiches +|* +|* Debug-Funktionen +|* die Debugging Tools geben rRange beim Eintritt und beim +|* Verlassen der Funktion aus +|* +|* Ersterstellung +|* VER0100 vb 901214 +|* +|* Stand +|* VER0100 vb 901214 +|* +*******************************************************************/ + + +/************************************************************************* +|* +|* SwNodes::SectionUpDown() +|* +|* Beschreibung +|* Methode setzt die Indizies die bei SectionUp oder SectionDwon +|* veraendert wurden wieder richtig, sodass die Ebenen wieder +|* Konsistent sind. +|* +|* Parameter +|* SwIndex & aStart StartNode !!! +|* SwIndex & aEnd EndPunkt +|* +|* Ersterstellung JP 23.04.91 +|* Letzte Aenderung JP 23.04.91 +|* +*************************************************************************/ +/*N*/ void SwNodes::SectionUpDown( const SwNodeIndex & aStart, const SwNodeIndex & aEnd ) +/*N*/ { +/*N*/ SwNode * pAktNode; +/*N*/ SwNodeIndex aTmpIdx( aStart, +1 ); +/*N*/ // das Array bildet einen Stack, es werden alle StartOfSelction's gesichert +/*N*/ SwSttNdPtrs aSttNdStack( 1, 5 ); +/*N*/ SwStartNode* pTmp = aStart.GetNode().GetStartNode(); +/*N*/ aSttNdStack.C40_INSERT( SwStartNode, pTmp, 0 ); +/*N*/ +/*N*/ // durchlaufe bis der erste zu aendernde Start-Node gefunden wurde +/*N*/ // ( Es wird vom eingefuegten EndNode bis nach vorne die Indexe gesetzt ) +/*N*/ for( ;; aTmpIdx++ ) +/*N*/ { +/*N*/ pAktNode = &aTmpIdx.GetNode(); +/*N*/ pAktNode->pStartOfSection = aSttNdStack[ aSttNdStack.Count()-1 ]; +/*N*/ +/*N*/ if( pAktNode->GetStartNode() ) +/*N*/ { +/*?*/ pTmp = (SwStartNode*)pAktNode; +/*?*/ aSttNdStack.C40_INSERT( SwStartNode, pTmp, aSttNdStack.Count() ); +/*N*/ } +/*N*/ else if( pAktNode->GetEndNode() ) +/*N*/ { +/*N*/ SwStartNode* pSttNd = aSttNdStack[ aSttNdStack.Count() - 1 ]; +/*N*/ pSttNd->pEndOfSection = (SwEndNode*)pAktNode; +/*N*/ aSttNdStack.Remove( aSttNdStack.Count() - 1 ); +/*N*/ if( aSttNdStack.Count() ) +/*?*/ continue; // noch genuegend EndNodes auf dem Stack +/*N*/ +/*N*/ else if( aTmpIdx < aEnd ) // Uebergewicht an StartNodes +/*N*/ // ist das Ende noch nicht erreicht, so hole den Start von +/*N*/ // der uebergeordneten Section +/*N*/ { +/*?*/ aSttNdStack.C40_INSERT( SwStartNode, pSttNd->pStartOfSection, 0 ); +/*N*/ } +/*N*/ else // wenn ueber den Bereich hinaus, dann Ende +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } + + + + +/******************************************************************* +|* +|* SwNodes::Delete +|* +|* Beschreibung +|* Spezielle Implementierung der Delete-Funktion des +|* variablen Array. Diese spezielle Implementierung ist +|* notwendig, da durch das Loeschen von Start- bzw. +|* Endnodes Inkonsistenzen entstehen koennen. Diese werden +|* durch diese Funktion beseitigt. +|* +|* Parameter +|* IN +|* SwIndex &rIndex bezeichnet die Position, an der +|* geloescht wird +|* rIndex ist nach Aufruf der Funktion unveraendert (Kopie?!) +|* USHORT nNodes bezeichnet die Anzahl der zu loeschenden +|* Nodes; ist auf 1 defaulted +|* +|* Debug-Funktionen +|* geben beim Eintritt in die Funktion Position und Anzahl +|* der zu loeschenden Nodes aus. +|* +|* Ersterstellung +|* VER0100 vb 901214 +|* +|* Stand +|* VER0100 vb 901214 +|* +*******************************************************************/ +/*N*/ void SwNodes::Delete(const SwNodeIndex &rIndex, ULONG nNodes) +/*N*/ { +/*N*/ USHORT nLevel = 0; // Level-Counter +/*N*/ SwNode * pAktNode; +/*N*/ +/*N*/ ULONG nCnt = Count() - rIndex.GetIndex() - 1; +/*N*/ if( nCnt > nNodes ) nCnt = nNodes; +/*N*/ +/*N*/ if( nCnt == 0 ) // keine Anzahl -> return +/*?*/ return; +/*N*/ +/*N*/ SwNodeRange aRg( rIndex, 0, rIndex, nCnt-1 ); +/*N*/ // ueberprufe ob rIndex..rIndex + nCnt ueber einen Bereich hinausragt !! +/*N*/ if( ( !aRg.aStart.GetNode().StartOfSectionIndex() && +/*N*/ !aRg.aStart.GetIndex() ) || +/*N*/ ! CheckNodesRange( aRg.aStart, aRg.aEnd ) ) +/*?*/ return; +/*N*/ +/*N*/ +/*N*/ // falls aEnd auf keinem ContentNode steht, dann suche den vorherigen +/*N*/ while( ( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() || +/*N*/ ( pAktNode->GetEndNode() && +/*N*/ !pAktNode->pStartOfSection->IsTableNode() )) +/*?*/ aRg.aEnd--; +/*N*/ +/*N*/ nCnt = 0; +/*N*/ // Start erhoehen, damit auf < abgefragt wird. ( bei <= kann es zu +/*N*/ // Problemen fuehren; ist aEnd == aStart und wird aEnd geloscht, +/*N*/ // so ist aEnd <= aStart +/*N*/ aRg.aStart--; +/*N*/ +/*N*/ BOOL bSaveInNodesDel = bInNodesDel; +/*N*/ bInNodesDel = TRUE; +/*N*/ BOOL bUpdateOutline = FALSE; +/*N*/ +/*N*/ // bis alles geloescht ist +/*N*/ while( aRg.aStart < aRg.aEnd ) +/*N*/ { +/*N*/ pAktNode = &aRg.aEnd.GetNode(); +/*N*/ +/*N*/ if( pAktNode->GetEndNode() ) +/*N*/ { +/*N*/ // die gesamte Section loeschen ? +/*N*/ if( pAktNode->StartOfSectionIndex() > aRg.aStart.GetIndex() ) +/*N*/ { +/*N*/ SwTableNode* pTblNd = pAktNode->pStartOfSection->GetTableNode(); +/*N*/ if( pTblNd ) +/*N*/ pTblNd->DelFrms(); +/*N*/ +/*N*/ SwNode *pNd, *pChkNd = pAktNode->pStartOfSection; +/*N*/ USHORT nIdxPos; +/*N*/ do { +/*N*/ pNd = &aRg.aEnd.GetNode(); +/*N*/ +/*N*/ if( pNd->IsTxtNode() ) +/*N*/ { +/*N*/ if( NO_NUMBERING != +/*N*/ ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel() && +/*N*/ pOutlineNds->Seek_Entry( pNd, &nIdxPos )) +/*N*/ { +/*?*/ // loesche die Gliederungs-Indizies. +/*?*/ pOutlineNds->Remove( nIdxPos ); +/*?*/ bUpdateOutline = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else if( pNd->IsEndNode() && +/*N*/ pNd->pStartOfSection->IsTableNode() ) +/*N*/ ((SwTableNode*)pNd->pStartOfSection)->DelFrms(); +/*N*/ +/*N*/ aRg.aEnd--; +/*N*/ nCnt++; +/*N*/ +/*N*/ } while( pNd != pChkNd ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ RemoveNode( aRg.aEnd.GetIndex()+1, nCnt, TRUE ); // loesche +/*?*/ nCnt = 0; +/*?*/ aRg.aEnd--; // vor den EndNode +/*?*/ nLevel++; +/*N*/ } +/*N*/ } +/*N*/ else if( pAktNode->GetStartNode() ) // StartNode gefunden +/*N*/ { +/*?*/ if( nLevel == 0 ) // es wird eine Stufe runter gestuft +/*?*/ { +/*?*/ if( nCnt ) +/*?*/ { +/*?*/ // loesche jetzt das Array +/*?*/ aRg.aEnd++; +/*?*/ RemoveNode( aRg.aEnd.GetIndex(), nCnt, TRUE ); +/*?*/ nCnt = 0; +/*?*/ } +/*?*/ } +/*?*/ else // es werden alle Nodes Innerhalb eines Start- und +/*?*/ { // End-Nodes geloescht, loesche mit Start/EndNode +/*?*/ RemoveNode( aRg.aEnd.GetIndex(), nCnt + 2, TRUE ); // loesche Array +/*?*/ nCnt = 0; +/*?*/ nLevel--; +/*?*/ } +/*?*/ +/*?*/ // nach dem loeschen kann aEnd auf einem EndNode stehen +/*?*/ // loesche alle leeren Start-/End-Node-Paare +/*?*/ SwNode* pTmpNode = aRg.aEnd.GetNode().GetEndNode(); +/*?*/ aRg.aEnd--; +/*?*/ while( pTmpNode && +/*?*/ ( pAktNode = &aRg.aEnd.GetNode())->GetStartNode() && +/*?*/ pAktNode->StartOfSectionIndex() ) +/*?*/ { +/*?*/ // loesche den EndNode und StartNode +/*?*/ DelNodes( aRg.aEnd, 2 ); +/*?*/ pTmpNode = aRg.aEnd.GetNode().GetEndNode(); +/*?*/ aRg.aEnd--; +/*?*/ } +/*N*/ } +/*N*/ else // normaler Node, also ins TmpArray einfuegen +/*N*/ { +/*N*/ SwTxtNode* pTxtNd = pAktNode->GetTxtNode(); +/*N*/ if( pTxtNd ) +/*N*/ { +/*N*/ if( NO_NUMBERING != pTxtNd->GetTxtColl()->GetOutlineLevel() ) +/*N*/ { // loesche die Gliederungs-Indizies. +/*N*/ pOutlineNds->Remove( pTxtNd ); +/*N*/ bUpdateOutline = TRUE; +/*N*/ } +/*N*/ pTxtNd->InvalidateNumRule(); +/*N*/ } +/*N*/ else if( pAktNode->IsCntntNode() ) +/*?*/ ((SwCntntNode*)pAktNode)->InvalidateNumRule(); +/*N*/ +/*N*/ aRg.aEnd--; +/*N*/ nCnt++; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ aRg.aEnd++; +/*N*/ if( nCnt != 0 ) +/*N*/ RemoveNode( aRg.aEnd.GetIndex(), nCnt, TRUE ); // loesche den Rest +/*N*/ +/*N*/ // loesche alle leeren Start-/End-Node-Paare +/*N*/ while( aRg.aEnd.GetNode().GetEndNode() && +/*N*/ ( pAktNode = &aRg.aStart.GetNode())->GetStartNode() && +/*N*/ pAktNode->StartOfSectionIndex() ) +/*N*/ // aber ja keinen der heiligen 5. +/*N*/ { +/*?*/ DelNodes( aRg.aStart, 2 ); // loesche den Start- und EndNode +/*?*/ aRg.aStart--; +/*N*/ } +/*N*/ +/*N*/ bInNodesDel = bSaveInNodesDel; +/*N*/ +/*N*/ if( !bInNodesDel ) +/*N*/ { +/*N*/ // rufe jetzt noch das Update fuer die Gliederung/Nummerierung auf +/*N*/ if( bUpdateOutline || bInDelUpdOutl ) +/*N*/ { +/*N*/ UpdtOutlineIdx( aRg.aEnd.GetNode() ); +/*N*/ bInDelUpdOutl = FALSE; +/*N*/ } +/*N*/ +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ if( bUpdateOutline ) +/*?*/ bInDelUpdOutl = TRUE; +/*N*/ } +/*N*/ } + +/******************************************************************* +|* +|* SwNodes::GetSectionLevel +|* +|* Beschreibung +|* Die Funktion liefert den Sectionlevel an der durch +|* aIndex bezeichneten Position. Die Funktion ruft die +|* GetSectionlevel-Funktion des durch aIndex bezeichneten +|* Nodes. Diese ist eine virtuelle Funktion, die fuer +|* Endnodes speziell implementiert werden musste. +|* Die Sectionlevels werden ermittelt, indem rekursiv durch +|* die Nodesstruktur (jeweils zum naechsten theEndOfSection) +|* gegangen wird, bis die oberste Ebene erreicht ist +|* (theEndOfSection == 0) +|* +|* Parameter +|* aIndex bezeichnet die Position des Nodes, dessen +|* Sectionlevel ermittelt werden soll. Hier wird eine Kopie +|* uebergeben, da eine Veraenderung der Variablen in der +|* rufenden Funktion nicht wuenschenswert ist. +|* +|* Ausnahmen +|* Der erste Node im Array sollte immer ein Startnode sein. +|* Dieser erfaehrt in der Funktion SwNodes::GetSectionLevel() +|* eine Sonderbehandlung; es wird davon ausgegangen, dass der +|* erste Node auch ein Startnode ist. +|* +|* Ersterstellung +|* VER0100 vb 901214 +|* +|* Stand +|* VER0100 vb 901214 +|* +*******************************************************************/ + +/*N*/ void SwNodes::GoStartOfSection(SwNodeIndex *pIdx) const +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } + +/*N*/ void SwNodes::GoEndOfSection(SwNodeIndex *pIdx) const +/*N*/ { +/*N*/ // falls er vor einem Endnode steht --> nichts tun +/*N*/ if( !pIdx->GetNode().IsEndNode() ) +/*N*/ (*pIdx) = *pIdx->GetNode().EndOfSectionNode(); +/*N*/ } + +/*N*/ SwCntntNode* SwNodes::GoNext(SwNodeIndex *pIdx) const +/*N*/ { +/*N*/ if( pIdx->GetIndex() >= Count() - 1 ) +/*?*/ return 0; +/*N*/ +/*N*/ SwNodeIndex aTmp(*pIdx, +1); +/*N*/ SwNode* pNd; +/*N*/ while( aTmp < Count()-1 && 0 == ( pNd = &aTmp.GetNode())->IsCntntNode() ) +/*N*/ aTmp++; +/*N*/ +/*N*/ if( aTmp == Count()-1 ) +/*N*/ pNd = 0; +/*N*/ else +/*N*/ (*pIdx) = aTmp; +/*N*/ return (SwCntntNode*)pNd; +/*N*/ } + +/*N*/ SwCntntNode* SwNodes::GoPrevious(SwNodeIndex *pIdx) const +/*N*/ { +/*N*/ if( !pIdx->GetIndex() ) +/*?*/ return 0; +/*N*/ +/*N*/ SwNodeIndex aTmp( *pIdx, -1 ); +/*N*/ SwNode* pNd; +/*N*/ while( aTmp.GetIndex() && 0 == ( pNd = &aTmp.GetNode())->IsCntntNode() ) +/*N*/ aTmp--; +/*N*/ +/*N*/ if( !aTmp.GetIndex() ) +/*?*/ pNd = 0; +/*N*/ else +/*N*/ (*pIdx) = aTmp; +/*N*/ return (SwCntntNode*)pNd; +/*N*/ } + +/*N*/ SwNode* SwNodes::GoNextWithFrm(SwNodeIndex *pIdx) const +/*N*/ { +/*N*/ if( pIdx->GetIndex() >= Count() - 1 ) +/*?*/ return 0; +/*N*/ +/*N*/ SwNodeIndex aTmp(*pIdx, +1); +/*N*/ SwNode* pNd; +/*N*/ while( aTmp < Count()-1 ) +/*N*/ { +/*N*/ pNd = &aTmp.GetNode(); +/*N*/ SwModify *pMod = 0; +/*N*/ if ( pNd->IsCntntNode() ) +/*N*/ pMod = (SwCntntNode*)pNd; +/*N*/ else if ( pNd->IsTableNode() ) +/*N*/ pMod = ((SwTableNode*)pNd)->GetTable().GetFrmFmt(); +/*N*/ else if( pNd->IsEndNode() && !pNd->FindStartNode()->IsSectionNode() ) +/*N*/ { +/*N*/ pNd = 0; +/*N*/ break; +/*N*/ } +/*N*/ if ( pMod && pMod->GetDepends() ) +/*N*/ { +/*N*/ SwClientIter aIter( *pMod ); +/*N*/ if( aIter.First( TYPE(SwFrm) ) ) +/*N*/ break; +/*N*/ } +/*N*/ aTmp++; +/*N*/ } +/*N*/ if( aTmp == Count()-1 ) +/*N*/ pNd = 0; +/*N*/ else if( pNd ) +/*N*/ (*pIdx) = aTmp; +/*N*/ return pNd; +/*N*/ } + + + + +/************************************************************************* +|* +|* BOOL SwNodes::CheckNodesRange() +|* +|* Beschreibung +|* Teste ob der uebergene SRange nicht ueber die Grenzen der +|* einzelnen Bereiche (PosIts, Autotext, Content, Icons und Inserts ) +|* hinaus reicht. +|* Nach Wahrscheinlichkeit des Ranges sortiert. +|* +|* Alg.: Da festgelegt ist, das aRange.aEnd den 1.Node hinter dem Bereich +|* bezeichnet, wird hier auf aEnd <= End.. getestet !! +|* +|* Parameter SwIndex & Start-Index vom Bereich +|* SwIndex & End-Index vom Bereich +|* BOOL TRUE: Start+End in gleicher Section! +|* FALSE: Start+End in verschiedenen Sect. +|* Return-Wert BOOL TRUE: gueltiger SRange +|* FALSE: ungueltiger SRange +|* +|* Ersterstellung JP 23.04.91 +|* Letzte Aenderung JP 18.06.92 +|* +*************************************************************************/ + +/*N*/ inline int TstIdx( ULONG nSttIdx, ULONG nEndIdx, ULONG nStt, ULONG nEnd ) +/*N*/ { +/*N*/ return nStt < nSttIdx && nEnd >= nSttIdx && +/*N*/ nStt < nEndIdx && nEnd >= nEndIdx; +/*N*/ } + +/*N*/ BOOL SwNodes::CheckNodesRange( const SwNodeIndex& rStt, const SwNodeIndex& rEnd ) const +/*N*/ { +/*N*/ ULONG nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex(); +/*N*/ if( TstIdx( nStt, nEnd, pEndOfContent->StartOfSectionIndex(), +/*N*/ pEndOfContent->GetIndex() )) return TRUE; +/*?*/ if( TstIdx( nStt, nEnd, pEndOfAutotext->StartOfSectionIndex(), +/*?*/ pEndOfAutotext->GetIndex() )) return TRUE; +/*?*/ if( TstIdx( nStt, nEnd, pEndOfPostIts->StartOfSectionIndex(), +/*?*/ pEndOfPostIts->GetIndex() )) return TRUE; +/*?*/ if( TstIdx( nStt, nEnd, pEndOfInserts->StartOfSectionIndex(), +/*?*/ pEndOfInserts->GetIndex() )) return TRUE; +/*?*/ if( TstIdx( nStt, nEnd, pEndOfRedlines->StartOfSectionIndex(), +/*?*/ pEndOfRedlines->GetIndex() )) return TRUE; +/*?*/ +/*?*/ return FALSE; // liegt irgendwo dazwischen, FEHLER +/*N*/ } + + +/************************************************************************* +|* +|* void SwNodes::DelNodes() +|* +|* Beschreibung +|* Loesche aus den NodesArray ab einer Position entsprechend Node's. +|* +|* Parameter SwIndex & Der Startpunkt im Nodes-Array +|* USHORT die Anzahl +|* +|* Ersterstellung JP 23.04.91 +|* Letzte Aenderung JP 23.04.91 +|* +*************************************************************************/ +/*N*/ void SwNodes::DelNodes( const SwNodeIndex & rStart, ULONG nCnt ) +/*N*/ { +/*N*/ int bUpdateNum = 0; +/*N*/ ULONG nSttIdx = rStart.GetIndex(); +/*N*/ +/*N*/ if( !nSttIdx && nCnt == GetEndOfContent().GetIndex()+1 ) +/*N*/ { +/*N*/ // es wird das gesamte Nodes-Array zerstoert, man ist im Doc DTOR! +/*N*/ // Die initialen Start-/End-Nodes duerfen nur im SwNodes-DTOR +/*N*/ // zerstoert werden! +/*N*/ SwNode* aEndNdArr[] = { pEndOfContent, +/*N*/ pEndOfPostIts, pEndOfInserts, +/*N*/ pEndOfAutotext, pEndOfRedlines, +/*N*/ 0 +/*N*/ }; +/*N*/ +/*N*/ SwNode** ppEndNdArr = aEndNdArr; +/*N*/ while( *ppEndNdArr ) +/*N*/ { +/*N*/ nSttIdx = (*ppEndNdArr)->StartOfSectionIndex() + 1; +/*N*/ ULONG nEndIdx = (*ppEndNdArr)->GetIndex(); +/*N*/ +/*N*/ if( nSttIdx != nEndIdx ) +/*N*/ RemoveNode( nSttIdx, nEndIdx - nSttIdx, TRUE ); +/*N*/ +/*N*/ ++ppEndNdArr; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ for( ULONG n = nSttIdx, nEnd = nSttIdx + nCnt; n < nEnd; ++n ) +/*N*/ { +/*N*/ SwNode* pNd = (*this)[ n ]; +/*N*/ +/*N*/ if( pNd->IsTxtNode() && +/*N*/ NO_NUMBERING != ((SwTxtNode*)pNd)->GetTxtColl()->GetOutlineLevel() ) +/*N*/ { // loesche die Gliederungs-Indizies. +/*?*/ USHORT nIdxPos; +/*?*/ if( pOutlineNds->Seek_Entry( pNd, &nIdxPos )) +/*?*/ { +/*?*/ pOutlineNds->Remove( nIdxPos ); +/*?*/ bUpdateNum = 1; +/*?*/ } +/*N*/ } +/*N*/ if( pNd->IsCntntNode() ) +/*N*/ ((SwCntntNode*)pNd)->InvalidateNumRule(); +/*N*/ } +/*N*/ RemoveNode( nSttIdx, nCnt, TRUE ); +/*N*/ +/*N*/ // rufe noch das Update fuer die Gliederungsnumerierung auf +/*N*/ if( bUpdateNum ) +/*?*/ UpdtOutlineIdx( rStart.GetNode() ); +/*N*/ } +/*N*/ } + + +/************************************************************************* +|* +|* USHORT HighestLevel( SwNodes & rNodes, const SwNodeRange & rRange ) +|* +|* Beschreibung +|* Berechne den hoehsten Level innerhalb des Bereiches +|* +|* Parameter SwNodes & das Node-Array +|* SwNodeRange & der zu ueberpruefende Bereich +|* Return USHORT der hoechste Level +|* +|* Ersterstellung JP 24.04.91 +|* Letzte Aenderung JP 24.04.91 +|* +*************************************************************************/ + + + + +/************************************************************************* +|* +|* SwNodes::Move() +|* +|* Beschreibung +|* Parameter SwPaM& zu kopierender Bereich +|* SwNodes& in dieses Nodes-Array +|* SwPosition& auf diese Position im Nodes-Array +|* Ersterstellung JP 09.07.92 +|* Letzte Aenderung JP 09.07.92 +|* +*************************************************************************/ + + + +/************************************************************************* +|* +|* SwNodes::_Copy() +|* +|* Beschreibung +|* Parameter SwNodeRange& zu kopierender Bereich +|* SwDoc& in dieses Dokument +|* SwIndex& auf diese Position im Nodes-Array +|* Ersterstellung JP 11.11.92 +|* Letzte Aenderung JP 11.11.92 +|* +*************************************************************************/ + +/*N*/ inline BYTE MaxLvl( BYTE nMin, BYTE nMax, short nNew ) +/*N*/ { +/*N*/ return (BYTE)(nNew < nMin ? nMin : nNew > nMax ? nMax : nNew); +/*N*/ } + +/*N*/ void SwNodes::_CopyNodes( const SwNodeRange& rRange, +/*N*/ const SwNodeIndex& rIndex, BOOL bNewFrms, BOOL bTblInsDummyNode ) const +/*N*/ { +/*N*/ SwDoc* pDoc = rIndex.GetNode().GetDoc(); +/*N*/ +/*N*/ SwNode * pAktNode; +/*N*/ if( rIndex == 0 || +/*N*/ ( (pAktNode = &rIndex.GetNode())->GetStartNode() && +/*N*/ !pAktNode->StartOfSectionIndex() )) +/*?*/ return; +/*N*/ +/*N*/ SwNodeRange aRg( rRange ); +/*N*/ +/*N*/ // "einfache" StartNodes oder EndNodes ueberspringen +/*N*/ while( ND_STARTNODE == (pAktNode = (*this)[ aRg.aStart ])->GetNodeType() +/*N*/ || ( pAktNode->IsEndNode() && +/*N*/ !pAktNode->pStartOfSection->IsSectionNode() ) ) +/*N*/ aRg.aStart++; +/*N*/ +/*N*/ // falls aEnd-1 auf keinem ContentNode steht, dann suche den vorherigen +/*N*/ aRg.aEnd--; +/*N*/ while( (( pAktNode = (*this)[ aRg.aEnd ])->GetStartNode() && +/*N*/ !pAktNode->IsSectionNode() ) || +/*N*/ ( pAktNode->IsEndNode() && +/*N*/ ND_STARTNODE == pAktNode->pStartOfSection->GetNodeType()) ) +/*N*/ aRg.aEnd--; +/*N*/ aRg.aEnd++; +/*N*/ +/*N*/ // wird im selben Array's verschoben, dann ueberpruefe die Einfuegepos. +/*N*/ if( aRg.aStart >= aRg.aEnd ) +/*?*/ return; +/*N*/ +/*N*/ if( this == &pDoc->GetNodes() && +/*N*/ rIndex.GetIndex() >= aRg.aStart.GetIndex() && +/*N*/ rIndex.GetIndex() < aRg.aEnd.GetIndex() ) +/*?*/ return; +/*N*/ +/*N*/ SwNodeIndex aInsPos( rIndex ); +/*N*/ SwNodeIndex aOrigInsPos( rIndex, -1 ); // Originale Insert Pos +/*N*/ USHORT nLevel = 0; // Level-Counter +/*N*/ +/*N*/ for( ULONG nNodeCnt = aRg.aEnd.GetIndex() - aRg.aStart.GetIndex(); +/*N*/ nNodeCnt > 0; --nNodeCnt ) +/*N*/ { +/*N*/ pAktNode = &aRg.aStart.GetNode(); +/*N*/ switch( pAktNode->GetNodeType() ) +/*N*/ { +/*N*/ case ND_TABLENODE: +/*N*/ // dann kopiere mal den TableNode +/*N*/ // Tabelle in Tabelle kopieren ? +/*N*/ // Tabell in Fussnote kopieren ? +/*N*/ if( pDoc->IsIdxInTbl( aInsPos ) || +/*N*/ ( aInsPos < pDoc->GetNodes().GetEndOfInserts().GetIndex() && +/*N*/ pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() +/*N*/ < aInsPos.GetIndex() )) +/*N*/ { +/*?*/ nNodeCnt -= +/*?*/ ( pAktNode->EndOfSectionIndex() - +/*?*/ aRg.aStart.GetIndex() ); +/*?*/ +/*?*/ // dann alle Nodes der Tabelle in die akt. Zelle kopieren +/*?*/ // fuer den TabellenNode einen DummyNode einfuegen? +/*?*/ if( bTblInsDummyNode ) +/*?*/ new SwNode( aInsPos, ND_SECTIONDUMMY ); +/*?*/ +/*?*/ for( aRg.aStart++; aRg.aStart.GetIndex() < +/*?*/ pAktNode->EndOfSectionIndex(); +/*?*/ aRg.aStart++ ) +/*?*/ { +/*?*/ // fuer den Box-StartNode einen DummyNode einfuegen? +/*?*/ if( bTblInsDummyNode ) +/*?*/ new SwNode( aInsPos, ND_SECTIONDUMMY ); +/*?*/ +/*?*/ SwStartNode* pSttNd = aRg.aStart.GetNode().GetStartNode(); +/*?*/ _CopyNodes( SwNodeRange( *pSttNd, + 1, +/*?*/ *pSttNd->EndOfSectionNode() ), +/*?*/ aInsPos, bNewFrms, FALSE ); +/*?*/ +/*?*/ // fuer den Box-EndNode einen DummyNode einfuegen? +/*?*/ if( bTblInsDummyNode ) +/*?*/ new SwNode( aInsPos, ND_SECTIONDUMMY ); +/*?*/ aRg.aStart = *pSttNd->EndOfSectionNode(); +/*?*/ } +/*?*/ // fuer den TabellenEndNode einen DummyNode einfuegen? +/*?*/ if( bTblInsDummyNode ) +/*?*/ new SwNode( aInsPos, ND_SECTIONDUMMY ); +/*?*/ aRg.aStart = *pAktNode->EndOfSectionNode(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwNodeIndex nStt( aInsPos, -1 ); +/*N*/ SwTableNode* pTblNd = ((SwTableNode*)pAktNode)-> +/*N*/ MakeCopy( pDoc, aInsPos ); +/*N*/ nNodeCnt -= aInsPos.GetIndex() - nStt.GetIndex() -2; +/*N*/ +/*N*/ aRg.aStart = pAktNode->EndOfSectionIndex(); +/*N*/ +/*N*/ if( bNewFrms && pTblNd ) +/*N*/ { +/*N*/ nStt = aInsPos; +/*N*/ pTblNd->MakeFrms( &nStt ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case ND_SECTIONNODE: // SectionNode +/*?*/ // der gesamte Bereich oder nur ein Teil ?? +/*?*/ if( pAktNode->EndOfSectionIndex() < aRg.aEnd.GetIndex() ) +/*?*/ { +/*?*/ // also der gesamte, lege einen neuen SectionNode an +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwNodeIndex nStt( aInsPos, -1 ); +/*?*/ } +/*?*/ break; +/*?*/ +/*N*/ case ND_STARTNODE: // StartNode gefunden +/*N*/ { +/*N*/ SwStartNode* pTmp = new SwStartNode( aInsPos, ND_STARTNODE, +/*N*/ ((SwStartNode*)pAktNode)->GetStartNodeType() ); +/*N*/ new SwEndNode( aInsPos, *pTmp ); +/*N*/ aInsPos--; +/*N*/ nLevel++; +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case ND_ENDNODE: +/*N*/ if( nLevel ) // vollstaendige Section +/*N*/ { +/*N*/ --nLevel; +/*N*/ aInsPos++; // EndNode schon vorhanden +/*N*/ } +/*N*/ else if( !pAktNode->pStartOfSection->IsSectionNode() ) +/*N*/ { +/*N*/ // erzeuge eine Section an der originalen InsertPosition +/*N*/ SwNodeRange aTmpRg( aOrigInsPos, 1, aInsPos ); +/*N*/ pDoc->GetNodes().SectionDown( &aTmpRg, +/*N*/ pAktNode->pStartOfSection->GetStartNodeType() ); +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case ND_TEXTNODE: +/*N*/ case ND_GRFNODE: +/*N*/ case ND_OLENODE: +/*N*/ { +/*N*/ SwCntntNode* pNew = ((SwCntntNode*)pAktNode)->MakeCopy( +/*N*/ pDoc, aInsPos ); +/*N*/ if( !bNewFrms ) // dflt. werden die Frames immer angelegt +/*N*/ pNew->DelFrms(); +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case ND_SECTIONDUMMY: + /*if( (const SwNodes*)this == GetDoc()->GetUndoNds() ) + { + // dann muss an der akt. InsPos auch ein SectionNode + // (Start/Ende) stehen; dann diesen ueberspringen. + // Andernfalls nicht weiter beachten. + SwNode* pTmpNd = pDoc->GetNodes()[ aInsPos ]; + if( pTmpNd->IsSectionNode() || + pTmpNd->FindStartNode()->IsSectionNode() ) + aInsPos++; // ueberspringen + } + else */ + ASSERT( FALSE, "wie kommt diser Node ins Nodes-Array??" ); + break; + +/*?*/ default: +/*?*/ ASSERT( FALSE, "weder Start-/End-/Content-Node, unbekannter Typ" ); +/*N*/ } +/*N*/ aRg.aStart++; +/*N*/ } +/*N*/ +/*N*/ +/*N*/ #ifdef JP_DEBUG +/*N*/ { +/*N*/ extern Writer* GetDebugWriter(const String&); +/*N*/ +/*N*/ Writer* pWriter = GetDebugWriter(aEmptyStr); +/*N*/ if( pWriter ) +/*N*/ { +/*N*/ int nError; +/*N*/ SvFileStream aStrm( "c:\\$$copy.db", STREAM_WRITE ); +/*N*/ SwWriter aWriter( aStrm, *pMyDoc ); +/*N*/ aWriter.Write( &nError, pWriter ); +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ } + +/*N*/ void SwNodes::_DelDummyNodes( const SwNodeRange& rRg ) +/*N*/ { +/*N*/ SwNodeIndex aIdx( rRg.aStart ); +/*N*/ while( aIdx.GetIndex() < rRg.aEnd.GetIndex() ) +/*N*/ { +/*N*/ if( ND_SECTIONDUMMY == aIdx.GetNode().GetNodeType() ) +/*?*/ RemoveNode( aIdx.GetIndex(), 1, TRUE ); +/*N*/ else +/*N*/ aIdx++; +/*N*/ } +/*N*/ } + +/*N*/ SwStartNode* SwNodes::MakeEmptySection( const SwNodeIndex& rIdx, +/*N*/ SwStartNodeType eSttNdTyp ) +/*N*/ { +/*N*/ SwStartNode* pSttNd = new SwStartNode( rIdx, ND_STARTNODE, eSttNdTyp ); +/*N*/ new SwEndNode( rIdx, *pSttNd ); +/*N*/ return pSttNd; +/*N*/ } + + +/*N*/ SwStartNode* SwNodes::MakeTextSection( const SwNodeIndex & rWhere, +/*N*/ SwStartNodeType eSttNdTyp, +/*N*/ SwTxtFmtColl *pColl, +/*N*/ SwAttrSet* pAutoAttr ) +/*N*/ { +/*N*/ SwStartNode* pSttNd = new SwStartNode( rWhere, ND_STARTNODE, eSttNdTyp ); +/*N*/ new SwEndNode( rWhere, *pSttNd ); +/*N*/ MakeTxtNode( SwNodeIndex( rWhere, - 1 ), pColl, pAutoAttr ); +/*N*/ return pSttNd; +/*N*/ } + + // zum naechsten Content-Node, der nicht geschuetzt oder versteckt ist + // (beides auf FALSE ==> GoNext/GoPrevious!!!) +/*N*/ SwCntntNode* SwNodes::GoNextSection( SwNodeIndex * pIdx, +/*N*/ int bSkipHidden, int bSkipProtect ) const +/*N*/ { +/*N*/ int bFirst = TRUE; +/*N*/ SwNodeIndex aTmp( *pIdx ); +/*N*/ const SwNode* pNd; +/*N*/ while( aTmp < Count() - 1 ) +/*N*/ { +/*N*/ if( ND_SECTIONNODE == ( pNd = (*this)[aTmp])->GetNodeType() ) +/*N*/ { +/*N*/ const SwSection& rSect = ((SwSectionNode*)pNd)->GetSection(); +/*N*/ if( (bSkipHidden && rSect.IsHiddenFlag()) || +/*N*/ (bSkipProtect && rSect.IsProtectFlag()) ) +/*N*/ // dann diese Section ueberspringen +/*?*/ aTmp = *pNd->EndOfSectionNode(); +/*N*/ bFirst = FALSE; +/*N*/ } +/*N*/ else if( bFirst ) +/*N*/ { +/*N*/ bFirst = FALSE; +/*N*/ if( pNd->pStartOfSection->IsSectionNode() ) +/*N*/ { +/*N*/ const SwSection& rSect = ((SwSectionNode*)pNd-> +/*N*/ pStartOfSection)->GetSection(); +/*N*/ if( (bSkipHidden && rSect.IsHiddenFlag()) || +/*N*/ (bSkipProtect && rSect.IsProtectFlag()) ) +/*N*/ // dann diese Section ueberspringen +/*N*/ aTmp = *pNd->EndOfSectionNode(); +/*N*/ } +/*N*/ } +/*N*/ else if( ND_CONTENTNODE & pNd->GetNodeType() ) +/*N*/ { +/*N*/ const SwSectionNode* pSectNd; +/*N*/ if( ( bSkipHidden || bSkipProtect ) && +/*N*/ 0 != (pSectNd = pNd->FindSectionNode() ) && +/*N*/ ( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) || +/*N*/ ( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) ) +/*N*/ { +/*?*/ aTmp = *pSectNd->EndOfSectionNode(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ (*pIdx) = aTmp; +/*N*/ return (SwCntntNode*)pNd; +/*N*/ } +/*N*/ } +/*N*/ aTmp++; +/*N*/ bFirst = FALSE; +/*N*/ } +/*?*/ return 0; +/*N*/ } + +/*N*/ SwCntntNode* SwNodes::GoPrevSection( SwNodeIndex * pIdx, +/*N*/ int bSkipHidden, int bSkipProtect ) const +/*N*/ { +/*N*/ int bFirst = TRUE; +/*N*/ SwNodeIndex aTmp( *pIdx ); +/*N*/ const SwNode* pNd; +/*N*/ while( aTmp > 0 ) +/*N*/ { +/*N*/ if( ND_ENDNODE == ( pNd = (*this)[aTmp])->GetNodeType() ) +/*N*/ { +/*N*/ if( pNd->pStartOfSection->IsSectionNode() ) +/*N*/ { +/*N*/ const SwSection& rSect = ((SwSectionNode*)pNd-> +/*N*/ pStartOfSection)->GetSection(); +/*N*/ if( (bSkipHidden && rSect.IsHiddenFlag()) || +/*N*/ (bSkipProtect && rSect.IsProtectFlag()) ) +/*N*/ // dann diese Section ueberspringen +/*?*/ aTmp = *pNd->StartOfSectionNode(); +/*N*/ } +/*N*/ bFirst = FALSE; +/*N*/ } +/*N*/ else if( bFirst ) +/*N*/ { +/*N*/ bFirst = FALSE; +/*N*/ if( pNd->pStartOfSection->IsSectionNode() ) +/*N*/ { +/*?*/ const SwSection& rSect = ((SwSectionNode*)pNd-> +/*?*/ pStartOfSection)->GetSection(); +/*?*/ if( (bSkipHidden && rSect.IsHiddenFlag()) || +/*?*/ (bSkipProtect && rSect.IsProtectFlag()) ) +/*?*/ // dann diese Section ueberspringen +/*?*/ aTmp = *pNd->StartOfSectionNode(); +/*N*/ } +/*N*/ } +/*N*/ else if( ND_CONTENTNODE & pNd->GetNodeType() ) +/*N*/ { +/*N*/ const SwSectionNode* pSectNd; +/*N*/ if( ( bSkipHidden || bSkipProtect ) && +/*N*/ 0 != (pSectNd = pNd->FindSectionNode() ) && +/*N*/ ( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) || +/*N*/ ( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) ) +/*N*/ { +/*?*/ aTmp = *pSectNd; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ (*pIdx) = aTmp; +/*N*/ return (SwCntntNode*)pNd; +/*N*/ } +/*N*/ } +/*N*/ aTmp--; +/*N*/ } +/*N*/ return 0; +/*N*/ } + + + // suche den vorhergehenden [/nachfolgenden ] ContentNode oder + // TabellenNode mit Frames. Wird kein Ende angeben, dann wird mit + // dem FrameIndex begonnen; ansonsten, wird mit dem vor rFrmIdx und + // dem hintern pEnd die Suche gestartet. Sollte kein gueltiger Node + // gefunden werden, wird 0 returnt. rFrmIdx zeigt auf dem Node mit + // Frames +/*N*/ SwNode* SwNodes::FindPrvNxtFrmNode( SwNodeIndex& rFrmIdx, +/*N*/ const SwNode* pEnd ) const +/*N*/ { +/*N*/ SwNode* pFrmNd = 0; +/*N*/ +/*N*/ // habe wir gar kein Layout, vergiss es +/*N*/ if( GetDoc()->GetRootFrm() ) +/*N*/ { +/*N*/ SwNode* pSttNd = &rFrmIdx.GetNode(); +/*N*/ +/*N*/ // wird in eine versteckte Section verschoben ?? +/*N*/ SwSectionNode* pSectNd = pSttNd->IsSectionNode() +/*N*/ ? pSttNd->FindStartNode()->FindSectionNode() +/*N*/ : pSttNd->FindSectionNode(); +/*N*/ if( !( pSectNd && pSectNd->GetSection().CalcHiddenFlag()/*IsHiddenFlag()*/ ) ) +/*N*/ { +/*N*/ SwNodeIndex aIdx( rFrmIdx ); +/*N*/ SwNode* pNd; +/*N*/ if( pEnd ) +/*N*/ { +/*N*/ aIdx--; +/*N*/ pNd = &aIdx.GetNode(); +/*N*/ } +/*N*/ else +/*?*/ pNd = pSttNd; +/*N*/ +/*N*/ if( ( pFrmNd = pNd )->IsCntntNode() ) +/*N*/ rFrmIdx = aIdx; +/*N*/ +/*N*/ // suche nach vorne/hinten nach einem Content Node +/*N*/ else if( 0 != ( pFrmNd = GoPrevSection( &aIdx, TRUE, FALSE )) && +/*N*/ ::binfilter::CheckNodesRange( aIdx, rFrmIdx, TRUE ) && +/*N*/ // nach vorne nie aus der Tabelle hinaus! +/*N*/ pFrmNd->FindTableNode() == pSttNd->FindTableNode() && +/*N*/ // Bug 37652: nach hinten nie aus der Tabellenzelle hinaus! +/*N*/ (!pFrmNd->FindTableNode() || pFrmNd->FindTableBoxStartNode() +/*N*/ == pSttNd->FindTableBoxStartNode() ) && +/*N*/ (!pSectNd || pSttNd->IsSectionNode() || +/*N*/ pSectNd->GetIndex() < pFrmNd->GetIndex()) +/*N*/ ) +/*N*/ { +/*N*/ rFrmIdx = aIdx; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pEnd ) +/*N*/ aIdx = pEnd->GetIndex() + 1; +/*N*/ else +/*?*/ aIdx = rFrmIdx; +/*N*/ +/*N*/ // JP 19.09.93: aber nie die Section dafuer verlassen !! +/*N*/ if( ( pEnd && ( pFrmNd = &aIdx.GetNode())->IsCntntNode() ) || +/*N*/ ( 0 != ( pFrmNd = GoNextSection( &aIdx, TRUE, FALSE )) && +/*N*/ ::binfilter::CheckNodesRange( aIdx, rFrmIdx, TRUE ) && +/*N*/ // JP 27.01.99: wenn der "Start"Node ein TabellenNode ist, +/*N*/ // dann kann der dahinter liegende nie der gleiche sein! +/*N*/ ( pSttNd->IsTableNode() || +/*N*/ ( pFrmNd->FindTableNode() == pSttNd->FindTableNode() && +/*N*/ // Bug 37652: nach hinten nie aus der Tabellenzelle hinaus! +/*N*/ (!pFrmNd->FindTableNode() || pFrmNd->FindTableBoxStartNode() +/*N*/ == pSttNd->FindTableBoxStartNode() ))) && +/*N*/ (!pSectNd || pSttNd->IsSectionNode() || +/*N*/ pSectNd->EndOfSectionIndex() > pFrmNd->GetIndex()) +/*N*/ )) +/*N*/ { +/*N*/ //JP 18.02.99: Undo von Merge einer Tabelle mit der +/*N*/ // der vorherigen, wenn dahinter auch noch eine steht +/*N*/ // falls aber der Node in einer Tabelle steht, muss +/*N*/ // natuerlich dieser returnt werden, wenn der SttNode eine +/*N*/ // Section oder Tabelle ist! +/*N*/ SwTableNode* pTblNd; +/*N*/ if( ( pSttNd->IsTableNode() ) && +/*N*/ 0 != ( pTblNd = pFrmNd->FindTableNode() )) +/*N*/ { +/*?*/ pFrmNd = pTblNd; +/*?*/ rFrmIdx = *pFrmNd; +/*N*/ } +/*N*/ else +/*N*/ rFrmIdx = aIdx; +/*N*/ } +/*N*/ else if( pNd->IsEndNode() && pNd->FindStartNode()->IsTableNode() ) +/*N*/ { +/*?*/ pFrmNd = pNd->FindStartNode(); +/*?*/ rFrmIdx = *pFrmNd; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ if( pEnd ) +/*?*/ aIdx = pEnd->GetIndex() + 1; +/*?*/ else +/*?*/ aIdx = rFrmIdx.GetIndex() + 1; +/*?*/ +/*?*/ if( (pFrmNd = &aIdx.GetNode())->IsTableNode() ) +/*?*/ rFrmIdx = aIdx; +/*?*/ else +/*?*/ { +/*?*/ pFrmNd = 0; +/*?*/ +/*?*/ // is there some sectionnodes before a tablenode? +/*?*/ while( aIdx.GetNode().IsSectionNode() ) +/*?*/ { +/*?*/ const SwSection& rSect = aIdx.GetNode(). +/*?*/ GetSectionNode()->GetSection(); +/*?*/ if( rSect.IsHiddenFlag() ) +/*?*/ aIdx = aIdx.GetNode().EndOfSectionIndex()+1; +/*?*/ else +/*?*/ aIdx++; +/*?*/ } +/*?*/ if( aIdx.GetNode().IsTableNode() ) +/*?*/ { +/*?*/ rFrmIdx = aIdx; +/*?*/ pFrmNd = &aIdx.GetNode(); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pFrmNd; +/*N*/ } + + +/*N*/ void SwNodes::ForEach( const SwNodeIndex& rStart, const SwNodeIndex& rEnd, +/*N*/ FnForEach_SwNodes fnForEach, void* pArgs ) +/*N*/ { +/*N*/ BigPtrArray::ForEach( rStart.GetIndex(), rEnd.GetIndex(), +/*N*/ (FnForEach) fnForEach, pArgs ); +/*N*/ } + +/*N*/ struct _TempBigPtrEntry : public BigPtrEntry +/*N*/ { +/*N*/ _TempBigPtrEntry() {} +/*N*/ }; + + +/*N*/ void SwNodes::RemoveNode( ULONG nDelPos, ULONG nSize, FASTBOOL bDel ) +/*N*/ { +/*N*/ ULONG nEnd = nDelPos + nSize; +/*N*/ SwNode* pNew = (*this)[ nEnd ]; +/*N*/ +/*N*/ if( pRoot ) +/*N*/ { +/*N*/ SwNodeIndex *p = pRoot; +/*N*/ while( p ) +/*N*/ { +/*N*/ ULONG nIdx = p->GetIndex(); +/*N*/ SwNodeIndex* pNext = p->pNext; +/*N*/ if( nDelPos <= nIdx && nIdx < nEnd ) +/*N*/ (*p) = *pNew; +/*N*/ +/*N*/ p = pNext; +/*N*/ } +/*N*/ +/*N*/ p = pRoot->pPrev; +/*N*/ while( p ) +/*N*/ { +/*?*/ ULONG nIdx = p->GetIndex(); +/*?*/ SwNodeIndex* pPrev = p->pPrev; +/*?*/ if( nDelPos <= nIdx && nIdx < nEnd ) +/*?*/ (*p) = *pNew; +/*?*/ +/*?*/ p = pPrev; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bDel ) +/*N*/ { +/*N*/ ULONG nCnt = nSize; +/*N*/ SwNode *pDel = (*this)[ nDelPos+nCnt-1 ], *pPrev = (*this)[ nDelPos+nCnt-2 ]; +/*N*/ +/*N*/ #if 1 +/*N*/ // temp. Object setzen +/*N*/ //JP 24.08.98: muessten eigentlich einzeln removed werden, weil +/*N*/ // das Remove auch rekursiv gerufen werden kann, z.B. bei +/*N*/ // zeichengebundenen Rahmen. Da aber dabei viel zu viel +/*N*/ // ablaueft, wird hier ein temp. Objekt eingefuegt, das +/*N*/ // dann mit dem Remove wieder entfernt wird. +/*N*/ // siehe Bug 55406 +/*N*/ _TempBigPtrEntry aTempEntry; +/*N*/ BigPtrEntry* pTempEntry = &aTempEntry; +/*N*/ +/*N*/ while( nCnt-- ) +/*N*/ { +/*N*/ delete pDel; +/*N*/ pDel = pPrev; +/*N*/ ULONG nPrevNdIdx = pPrev->GetIndex(); +/*N*/ BigPtrArray::Replace( nPrevNdIdx+1, pTempEntry ); +/*N*/ if( nCnt ) +/*N*/ pPrev = (*this)[ nPrevNdIdx - 1 ]; +/*N*/ } +/*N*/ nDelPos = pDel->GetIndex() + 1; +/*N*/ } +/*N*/ #else +/*N*/ // nach jedem Del ein Remove rufen - teuer! +/*N*/ //JP 24.08.98: muessen leider einzeln removed werden, weil das +/*N*/ // auch rekursiv gerufen wird - zeichengeb. Flys! +/*N*/ // siehe Bug 55406 +/*N*/ while( nCnt-- ) +/*N*/ { +/*N*/ delete pDel; +/*N*/ pDel = pPrev; +/*N*/ ULONG nPrevNdIdx = pPrev->GetIndex(); +/*N*/ BigPtrArray::Remove( nPrevNdIdx+1, 1 ); +/*N*/ if( nCnt ) +/*N*/ pPrev = (*this)[ nPrevNdIdx - 1 ]; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ #endif +/*N*/ +/*N*/ BigPtrArray::Remove( nDelPos, nSize ); +/*N*/ } + +/*N*/ void SwNodes::RegisterIndex( SwNodeIndex& rIdx ) +/*N*/ { +/*N*/ if( !pRoot ) // noch keine Root gesetzt? +/*N*/ { +/*N*/ pRoot = &rIdx; +/*N*/ pRoot->pPrev = 0; +/*N*/ pRoot->pNext = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // immer hinter die Root haengen +/*N*/ rIdx.pNext = pRoot->pNext; +/*N*/ pRoot->pNext = &rIdx; +/*N*/ rIdx.pPrev = pRoot; +/*N*/ if( rIdx.pNext ) +/*N*/ rIdx.pNext->pPrev = &rIdx; +/*N*/ } +/*N*/ } + +/*N*/ void SwNodes::DeRegisterIndex( SwNodeIndex& rIdx ) +/*N*/ { +/*N*/ register SwNodeIndex* pN = rIdx.pNext; +/*N*/ register SwNodeIndex* pP = rIdx.pPrev; +/*N*/ +/*N*/ if( pRoot == &rIdx ) +/*N*/ pRoot = pP ? pP : pN; +/*N*/ +/*N*/ if( pP ) +/*N*/ pP->pNext = pN; +/*N*/ if( pN ) +/*N*/ pN->pPrev = pP; +/*N*/ +/*N*/ rIdx.pNext = 0; +/*N*/ rIdx.pPrev = 0; +/*N*/ } + +/*N*/ void SwNodes::Insert( const SwNodePtr pNode, const SwNodeIndex& rPos ) +/*N*/ { +/*N*/ const ElementPtr pIns = pNode; +/*N*/ BigPtrArray::Insert( pIns, rPos.GetIndex() ); +/*N*/ } + +/*N*/ void SwNodes::Insert(const SwNodePtr pNode, ULONG nPos) +/*N*/ { +/*N*/ const ElementPtr pIns = pNode; +/*N*/ BigPtrArray::Insert( pIns, nPos ); +/*N*/ } + + // #i31620# + SwNode * SwNodes::operator[](int n) const + { + return operator[]((ULONG) n); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_section.cxx b/binfilter/bf_sw/source/core/docnode/sw_section.cxx new file mode 100644 index 000000000000..37c61be85fde --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_section.cxx @@ -0,0 +1,1150 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <stdlib.h> + +#include <hintids.hxx> + +#include <bf_svtools/intitem.hxx> +#include <bf_svtools/stritem.hxx> +#include <bf_sfx2/docfile.hxx> +#include <bf_sfx2/docfilt.hxx> +#include <bf_svx/protitem.hxx> +#include <bf_svx/linkmgr.hxx> +#include <tools/urlobj.hxx> + +#include <docary.hxx> +#include <fmtcntnt.hxx> +#include <errhdl.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <pam.hxx> +#include <editsh.hxx> +#include <hints.hxx> +#include <docsh.hxx> +#include <ndtxt.hxx> +#include <swserv.hxx> +#include <shellio.hxx> +#include <poolfmt.hxx> +#include <swbaslnk.hxx> +#include <mvsave.hxx> +#include <sectfrm.hxx> +#include <ftnidx.hxx> +#include <doctxm.hxx> + +#include <swerror.h> + +#include <frmatr.hxx> + +namespace binfilter { + +/*N*/ SV_IMPL_REF( SwServerObject ) + +//static const char __FAR_DATA sSectionFmtNm[] = "Section"; +#define sSectionFmtNm aEmptyStr + +/*N*/ class SwIntrnlSectRefLink : public SwBaseLink +/*N*/ { +/*N*/ SwSectionFmt& rSectFmt; +/*N*/ public: +/*N*/ SwIntrnlSectRefLink( SwSectionFmt& rFmt, USHORT nUpdateType, USHORT nFmt ) +/*N*/ : SwBaseLink( nUpdateType, nFmt ), +/*N*/ rSectFmt( rFmt ) +/*N*/ {} +/*N*/ +/*N*/ virtual void DataChanged( const String& rMimeType, +/*N*/ const ::com::sun::star::uno::Any & rValue ); +/*N*/ +/*N*/ virtual BOOL IsInRange( ULONG nSttNd, ULONG nEndNd, xub_StrLen nStt = 0, +/*N*/ xub_StrLen nEnd = STRING_NOTFOUND ) const; +/*N*/ }; + + +/*N*/ TYPEINIT1(SwSectionFmt,SwFrmFmt ); +/*N*/ TYPEINIT1(SwSection,SwClient ); + +/*N*/ typedef SwSection* SwSectionPtr; + +/*N*/ SV_IMPL_PTRARR(SwSectionFmts,SwSectionFmt*) + + + +/*N*/ SwSection::SwSection( SectionType eTyp, const String& rName, +/*N*/ SwSectionFmt* pFmt ) +/*N*/ : SwClient( pFmt ), +/*N*/ eType( eTyp ), sSectionNm( rName ) +/*N*/ { +/*N*/ bHidden = FALSE; +/*N*/ bHiddenFlag = FALSE; +/*N*/ bProtectFlag = FALSE; +/*N*/ bCondHiddenFlag = TRUE; +/*N*/ bConnectFlag = TRUE; +/*N*/ +/*N*/ SwSectionPtr pParentSect = GetParent(); +/*N*/ if( pParentSect ) +/*N*/ { +/*N*/ FASTBOOL bPHFlag = pParentSect->IsHiddenFlag(); +/*N*/ if( pParentSect->IsHiddenFlag() ) +/*?*/ SetHidden( TRUE ); +/*N*/ +/*N*/ _SetProtectFlag( pParentSect->IsProtectFlag() ); +/*N*/ } +/*N*/ +/*N*/ if( pFmt && !bProtectFlag ) +/*N*/ _SetProtectFlag( pFmt->GetProtect().IsCntntProtected() ); +/*N*/ } + + +/*N*/ SwSection::~SwSection() +/*N*/ { +/*N*/ SwSectionFmt* pFmt = GetFmt(); +/*N*/ if( !pFmt ) +/*N*/ return; +/*N*/ +/*N*/ SwDoc* pDoc = pFmt->GetDoc(); +/*N*/ if( pDoc->IsInDtor() ) +/*N*/ { +/*N*/ // dann melden wir noch schnell unser Format um ans dflt FrameFmt, +/*N*/ // damit es keine Abhaengigkeiten gibt +/*N*/ if( pFmt->DerivedFrom() != pDoc->GetDfltFrmFmt() ) +/*N*/ pDoc->GetDfltFrmFmt()->Add( pFmt ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pFmt->Remove( this ); // austragen, +/*N*/ +/*N*/ if( CONTENT_SECTION != eType ) // den Link austragen +/*N*/ pDoc->GetLinkManager().Remove( refLink ); +/*N*/ +/*N*/ if( refObj.Is() ) // als Server austragen +/*?*/ pDoc->GetLinkManager().RemoveServer( &refObj ); +/*N*/ +/*N*/ // ist die Section der letzte Client im Format, kann dieses +/*N*/ // geloescht werden +/*N*/ SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFmt ); +/*N*/ pFmt->Modify( &aMsgHint, &aMsgHint ); +/*N*/ if( !pFmt->GetDepends() ) +/*N*/ { +/*?*/ // Bug: 28191 - nicht ins Undo aufnehmen, sollte schon vorher +/*?*/ // geschehen sein!! +/*?*/ pDoc->DelSectionFmt( pFmt ); // und loeschen +/*N*/ } +/*N*/ } +/*N*/ if( refObj.Is() ) +/*N*/ refObj->Closed(); +/*N*/ } + + +/*N*/ SwSection& SwSection::operator=( const SwSection& rCpy ) +/*N*/ { +/*N*/ sSectionNm = rCpy.sSectionNm; +/*N*/ sCondition = rCpy.sCondition; +/*N*/ sLinkFileName = rCpy.GetLinkFileName(); +/*N*/ SetLinkFilePassWd( rCpy.GetLinkFilePassWd() ); +/*N*/ SetConnectFlag( rCpy.IsConnectFlag() ); +/*N*/ SetPasswd( rCpy.GetPasswd() ); +/*N*/ +/*N*/ eType = rCpy.eType; +/*N*/ +/*N*/ if( !GetFmt() ) +/*N*/ SetProtect( rCpy.IsProtect() ); +/*N*/ else if( rCpy.GetFmt() ) +/*?*/ _SetProtectFlag( rCpy.bProtectFlag ); +/*N*/ else +/*N*/ SetProtect( rCpy.bProtectFlag ); +/*N*/ +/*N*/ bCondHiddenFlag = TRUE; // sollte immer defaultet werden +/*N*/ SetHidden( rCpy.bHidden ); +/*N*/ +/*N*/ return *this; +/*N*/ } + + +/*N*/ int SwSection::operator==( const SwSection& rCmp ) const +/*N*/ { +/*N*/ return sSectionNm == rCmp.sSectionNm && +/*N*/ sCondition == rCmp.sCondition && +/*N*/ eType == rCmp.eType && +/*N*/ bHidden == rCmp.bHidden && +/*N*/ IsProtect() == rCmp.IsProtect() && +/*N*/ GetLinkFileName() == rCmp.GetLinkFileName() && +/*N*/ GetLinkFilePassWd() == rCmp.GetLinkFilePassWd() && +/*N*/ GetPasswd() == rCmp.GetPasswd() && +/*N*/ ( !GetFmt() || !rCmp.GetFmt() || GetFmt() == rCmp.GetFmt()); +/*N*/ } + + +void SwSection::_SetHiddenFlag( int bHidden, int bCondition ) +{ + SwSectionFmt* pFmt = GetFmt(); + if( pFmt ) + { + int bHide = bHidden && bCondition; + + if( bHide ) // die Nodes also "verstecken" + { + if( !bHiddenFlag ) // ist nicht versteckt + { + // wie sieht es mit dem Parent aus, ist der versteckt ? + // (eigentlich muesste das vom bHiddenFlag angezeigt werden!) + + // erstmal allen Childs sagen, das sie versteckt sind + SwMsgPoolItem aMsgItem( RES_SECTION_HIDDEN ); + pFmt->Modify( &aMsgItem, &aMsgItem ); + + // alle Frames loeschen + pFmt->DelFrms(); + } + } + else if( bHiddenFlag ) // die Nodes wieder anzeigen + { + // alle Frames sichtbar machen ( Childs Sections werden vom + // MakeFrms beruecksichtigt). Aber nur wenn die ParentSection + // nichts dagegen hat ! + SwSection* pParentSect = pFmt->GetParentSection(); + if( !pParentSect || !pParentSect->IsHiddenFlag() ) + { + // erstmal allen Childs sagen, das der Parent nicht mehr + // versteckt ist + SwMsgPoolItem aMsgItem( RES_SECTION_NOT_HIDDEN ); + pFmt->Modify( &aMsgItem, &aMsgItem ); + + pFmt->MakeFrms(); + } + } + } +} + +/*N*/ int SwSection::CalcHiddenFlag() const +/*N*/ { +/*N*/ const SwSection* pSect = this; +/*N*/ do { +/*N*/ if( pSect->IsHidden() && pSect->IsCondHidden() ) +/*?*/ return TRUE; +/*N*/ } while( 0 != ( pSect = pSect->GetParent()) ); +/*N*/ +/*N*/ return FALSE; +/*N*/ } + +/*N*/ int SwSection::_IsProtect() const +/*N*/ { +/*N*/ return GetFmt()->GetProtect().IsCntntProtected(); +/*N*/ } + + +/*N*/ void SwSection::SetHidden( int bFlag ) +/*N*/ { +/*N*/ if( bHidden == bFlag ) +/*N*/ return; +/*N*/ +/*?*/ bHidden = bFlag; +/*?*/ _SetHiddenFlag( bHidden, bCondHiddenFlag ); +/*N*/ } + + +/*N*/ void SwSection::SetProtect( int bFlag ) +/*N*/ { +/*N*/ if( GetFmt() ) +/*N*/ { +/*N*/ SvxProtectItem aItem; +/*N*/ aItem.SetCntntProtect( (BOOL)bFlag ); +/*N*/ GetFmt()->SetAttr( aItem ); +/*N*/ } +/*N*/ else +/*N*/ bProtectFlag = bFlag; +/*N*/ } + + +/*N*/ void SwSection::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +/*N*/ { +/*N*/ BOOL bRemake = FALSE, bUpdateFtn = FALSE; +/*N*/ switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ) +/*N*/ { +/*N*/ case RES_ATTRSET_CHG: +/*N*/ { +/*N*/ SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet(); +/*N*/ SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet(); +/*N*/ const SfxPoolItem* pItem; +/*N*/ +/*N*/ if( SFX_ITEM_SET == pNewSet->GetItemState( +/*N*/ RES_PROTECT, FALSE, &pItem ) ) +/*N*/ { +/*?*/ _SetProtectFlag( ((SvxProtectItem*)pItem)->IsCntntProtected() ); +/*?*/ pNewSet->ClearItem( RES_PROTECT ); +/*?*/ pOldSet->ClearItem( RES_PROTECT ); +/*N*/ } +/*N*/ +/*N*/ if( SFX_ITEM_SET == pNewSet->GetItemState( +/*N*/ RES_FTN_AT_TXTEND, FALSE, &pItem ) || +/*N*/ SFX_ITEM_SET == pNewSet->GetItemState( +/*N*/ RES_END_AT_TXTEND, FALSE, &pItem )) +/*?*/ bUpdateFtn = TRUE; +/*N*/ +/*N*/ if( !pNewSet->Count() ) +/*?*/ return; +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_PROTECT: +/*N*/ if( pNew ) +/*N*/ { +/*N*/ BOOL bNewFlag = ((SvxProtectItem*)pNew)->IsCntntProtected(); +/*N*/ if( !bNewFlag ) +/*N*/ { +/*N*/ // Abschalten: teste ob nicht vielleich ueber die Parents +/*N*/ // doch ein Schutzt besteht! +/*N*/ const SwSection* pSect = this; +/*N*/ do { +/*N*/ if( pSect->IsProtect() ) +/*N*/ { +/*N*/ bNewFlag = TRUE; +/*N*/ break; +/*N*/ } +/*N*/ } while( 0 != ( pSect = pSect->GetParent()) ); +/*N*/ } +/*N*/ +/*N*/ _SetProtectFlag( bNewFlag ); +/*N*/ } +/*N*/ return; +/*N*/ +/*?*/ case RES_SECTION_HIDDEN: +/*?*/ bHiddenFlag = TRUE; +/*?*/ return; +/*?*/ +/*?*/ case RES_SECTION_NOT_HIDDEN: +/*?*/ case RES_SECTION_RESETHIDDENFLAG: +/*?*/ bHiddenFlag = bHidden && bCondHiddenFlag; +/*?*/ return; +/*?*/ +/*?*/ case RES_COL: +/*?*/ /* wird ggf. vom Layout erledigt */ +/*?*/ break; +/*?*/ +/*?*/ case RES_FTN_AT_TXTEND: +/*?*/ if( pNew && pOld ) +/*?*/ bUpdateFtn = TRUE; +/*?*/ break; +/*?*/ +/*?*/ case RES_END_AT_TXTEND: +/*?*/ if( pNew && pOld ) +/*?*/ bUpdateFtn = TRUE; +/*?*/ break; +/*N*/ } +/*N*/ +/*N*/ if( bRemake ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 GetFmt()->DelFrms(); +/*N*/ } +/*N*/ +/*N*/ if( bUpdateFtn ) +/*N*/ { +/*?*/ SwSectionNode* pSectNd = GetFmt()->GetSectionNode( FALSE ); +/*?*/ if( pSectNd ) +/*?*/ pSectNd->GetDoc()->GetFtnIdxs().UpdateFtn(SwNodeIndex( *pSectNd )); +/*N*/ } +/*N*/ SwClient::Modify( pOld, pNew ); +/*N*/ } + +/*N*/ void SwSection::SetRefObject( SwServerObject* pObj ) +/*N*/ { +/*N*/ refObj = pObj; +/*N*/ } + + +void SwSection::SetCondHidden( int bFlag ) +{ + if( bCondHiddenFlag == bFlag ) + return; + + bCondHiddenFlag = bFlag; + _SetHiddenFlag( bHidden, bCondHiddenFlag ); +} + + +// setze/erfrage den gelinkten FileNamen +/*N*/ const String& SwSection::GetLinkFileName() const +/*N*/ { +/*N*/ if( refLink.Is() ) +/*N*/ { +/*N*/ String sTmp; +/*N*/ switch( eType ) +/*N*/ { +/*N*/ case DDE_LINK_SECTION: +/*?*/ sTmp = refLink->GetLinkSourceName(); +/*?*/ break; +/*N*/ +/*N*/ case FILE_LINK_SECTION: +/*N*/ { +/*N*/ String sRange, sFilter; +/*N*/ if( refLink->GetLinkManager() && +/*N*/ refLink->GetLinkManager()->GetDisplayNames( +/*N*/ refLink, 0, &sTmp, &sRange, &sFilter ) ) +/*N*/ { +/*N*/ ( sTmp += ::binfilter::cTokenSeperator ) += sFilter; +/*N*/ ( sTmp += ::binfilter::cTokenSeperator ) += sRange; +/*N*/ } +/*N*/ else if( GetFmt() && !GetFmt()->GetSectionNode() ) +/*N*/ { +/*N*/ // ist die Section im UndoNodesArray, dann steht +/*N*/ // der Link nicht im LinkManager, kann also auch nicht +/*N*/ // erfragt werden. Dann returne den akt. Namen +/*?*/ return sLinkFileName; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ ((SwSection*)this)->sLinkFileName = sTmp; +/*N*/ } +/*N*/ return sLinkFileName; +/*N*/ } + + +/*N*/ void SwSection::SetLinkFileName( const String& rNew, const String* pPassWd ) +/*N*/ { +/*N*/ if( refLink.Is() ) +/*?*/ refLink->SetLinkSourceName( rNew ); +/*N*/ else +/*N*/ sLinkFileName = rNew; +/*N*/ if( pPassWd ) +/*?*/ SetLinkFilePassWd( *pPassWd ); +/*N*/ } + +// falls es ein gelinkter Bereich war, dann muessen alle +// Child-Verknuepfungen sichtbar bemacht werden. + + +/*N*/ SwSectionFmt::SwSectionFmt( SwSectionFmt* pDrvdFrm, SwDoc *pDoc ) +/*N*/ : SwFrmFmt( pDoc->GetAttrPool(), sSectionFmtNm, pDrvdFrm ) +/*N*/ { +/*N*/ LockModify(); +/*N*/ SetAttr( *GetDfltAttr( RES_COL ) ); +/*N*/ UnlockModify(); +/*N*/ } + +/*N*/ SwSectionFmt::~SwSectionFmt() +/*N*/ { +/*N*/ if( !GetDoc()->IsInDtor() ) +/*N*/ { +/*N*/ SwSectionNode* pSectNd; +/*N*/ const SwNodeIndex* pIdx = GetCntnt( FALSE ).GetCntntIdx(); +/*N*/ if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() && +/*N*/ 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwSection& rSect = pSectNd->GetSection(); +/*N*/ } +/*N*/ LockModify(); +/*N*/ ResetAttr( RES_CNTNT ); +/*N*/ UnlockModify(); +/*N*/ } +/*N*/ } + + +/*N*/ SwSectionPtr SwSectionFmt::_GetSection() const +/*N*/ { +/*N*/ if( GetDepends() ) +/*N*/ { +/*N*/ SwClientIter aIter( *(SwSectionFmt*)this ); +/*N*/ return (SwSectionPtr)aIter.First( TYPE(SwSection) ); +/*N*/ } +/*N*/ +/*?*/ ASSERT( FALSE, "keine Section als Client." ) +/*?*/ return 0; +/*N*/ } + +/*N*/ extern void lcl_DeleteFtn( SwSectionNode *pNd, ULONG nStt, ULONG nEnd ); + +//Vernichtet alle Frms in aDepend (Frms werden per PTR_CAST erkannt). +/*N*/ void SwSectionFmt::DelFrms() +/*N*/ { +/*N*/ SwSectionNode* pSectNd; +/*N*/ const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx(); +/*N*/ if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() && +/*N*/ 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) +/*N*/ { +/*N*/ SwClientIter aIter( *this ); +/*N*/ SwClient *pLast = aIter.GoStart(); +/*N*/ while ( pLast ) +/*N*/ { +/*N*/ if ( pLast->IsA( TYPE(SwFrm) ) ) +/*N*/ { +/*N*/ SwSectionFrm *pFrm = (SwSectionFrm*)pLast; +/*N*/ SwSectionFrm::MoveCntntAndDelete( pFrm, FALSE ); +/*N*/ pLast = aIter.GoStart(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( pLast->IsA( TYPE(SwSectionFmt) ) ) +/*?*/ ((SwSectionFmt*)pLast)->DelFrms(); +/*N*/ pLast = aIter++; +/*N*/ } +/*N*/ } +/*N*/ ULONG nEnde = pSectNd->EndOfSectionIndex(); +/*N*/ ULONG nStart = pSectNd->GetIndex()+1; +/*N*/ lcl_DeleteFtn( pSectNd, nStart, nEnde ); +/*N*/ } +/*N*/ if( pIdx ) +/*N*/ { +/*N*/ //JP 22.09.98: +/*N*/ //Hint fuer Pagedesc versenden. Das mueste eigntlich das Layout im +/*N*/ //Paste der Frames selbst erledigen, aber das fuehrt dann wiederum +/*N*/ //zu weiteren Folgefehlern, die mit Laufzeitkosten geloest werden +/*N*/ //muesten. #56977# #55001# #56135# +/*N*/ SwNodeIndex aNextNd( *pIdx ); +/*N*/ SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( &aNextNd, TRUE, FALSE ); +/*N*/ if( pCNd ) +/*N*/ { +/*N*/ const SfxPoolItem& rItem = pCNd->GetSwAttrSet().Get( RES_PAGEDESC ); +/*N*/ pCNd->Modify( (SfxPoolItem*)&rItem, (SfxPoolItem*)&rItem ); +/*N*/ } +/*N*/ } +/*N*/ } + + +//Erzeugt die Ansichten +void SwSectionFmt::MakeFrms() +{ + SwSectionNode* pSectNd; + const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx(); + + if( pIdx && &GetDoc()->GetNodes() == &pIdx->GetNodes() && + 0 != (pSectNd = pIdx->GetNode().GetSectionNode() )) + { + SwNodeIndex aIdx( *pIdx ); + pSectNd->MakeFrms( &aIdx ); + } +} + +/*N*/ void lcl_ClientIter( SwSectionFmt* pFmt, const SfxPoolItem* pOld, +/*N*/ const SfxPoolItem* pNew ) +/*N*/ { +/*N*/ SwClientIter aIter( *pFmt ); +/*N*/ SwClient * pLast = aIter.GoStart(); +/*N*/ if( pLast ) +/*N*/ do { +/*N*/ pLast->Modify( (SfxPoolItem*)pOld, (SfxPoolItem*)pNew ); +/*N*/ } while( 0 != ( pLast = aIter++ )); +/*N*/ } + +/*N*/ void SwSectionFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +/*N*/ { +/*N*/ BOOL bClients = FALSE; +/*N*/ USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ switch( nWhich ) +/*N*/ { +/*N*/ case RES_ATTRSET_CHG: +/*N*/ if( GetDepends() ) +/*N*/ { +/*N*/ SfxItemSet* pNewSet = ((SwAttrSetChg*)pNew)->GetChgSet(); +/*N*/ SfxItemSet* pOldSet = ((SwAttrSetChg*)pOld)->GetChgSet(); +/*N*/ const SfxPoolItem *pItem; +/*N*/ if( SFX_ITEM_SET == pNewSet->GetItemState( +/*N*/ RES_PROTECT, FALSE, &pItem )) +/*N*/ { +/*N*/ lcl_ClientIter( this, pItem, pItem ); +/*N*/ pNewSet->ClearItem( RES_PROTECT ); +/*N*/ pOldSet->ClearItem( RES_PROTECT ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pNewSet->GetItemState( +/*N*/ RES_FTN_AT_TXTEND, FALSE, &pItem )) +/*N*/ { +/*?*/ lcl_ClientIter( this, &pOldSet->Get( RES_FTN_AT_TXTEND ), +/*?*/ pItem ); +/*?*/ pNewSet->ClearItem( RES_FTN_AT_TXTEND ); +/*?*/ pOldSet->ClearItem( RES_FTN_AT_TXTEND ); +/*N*/ } +/*N*/ if( SFX_ITEM_SET == pNewSet->GetItemState( +/*N*/ RES_END_AT_TXTEND, FALSE, &pItem )) +/*N*/ { +/*?*/ lcl_ClientIter( this, &pOldSet->Get( RES_END_AT_TXTEND ), +/*?*/ pItem ); +/*?*/ pNewSet->ClearItem( RES_END_AT_TXTEND ); +/*?*/ pOldSet->ClearItem( RES_END_AT_TXTEND ); +/*N*/ } +/*N*/ if( !((SwAttrSetChg*)pOld)->GetChgSet()->Count() ) +/*N*/ return; +/*N*/ } +/*N*/ break; +/*N*/ +/*?*/ case RES_SECTION_RESETHIDDENFLAG: +/*?*/ case RES_FTN_AT_TXTEND: +/*?*/ case RES_END_AT_TXTEND : bClients = TRUE; +/*?*/ // no break !! +/*?*/ case RES_SECTION_HIDDEN: +/*?*/ case RES_SECTION_NOT_HIDDEN: +/*?*/ { +/*?*/ SwSection* pSect = GetSection(); +/*?*/ if( pSect && ( bClients || ( RES_SECTION_HIDDEN == nWhich ? +/*?*/ !pSect->IsHiddenFlag() : pSect->IsHiddenFlag() ) ) ) +/*?*/ { +/*?*/ // selbst ueber die Clients iterieren, sollte schneller sein! +/*?*/ SwClientIter aIter( *this ); +/*?*/ SwClient * pLast = aIter.GoStart(); +/*?*/ do { +/*?*/ pLast->Modify( pOld, pNew ); +/*?*/ } while( 0 != ( pLast = aIter++ )); +/*?*/ } +/*?*/ } +/*?*/ return ; +/*?*/ +/*?*/ +/*?*/ case RES_PROTECT: +/*?*/ // diese Messages bis zum Ende des Baums durchreichen ! +/*?*/ if( GetDepends() ) +/*?*/ { +/*?*/ SwClientIter aIter( *this ); +/*?*/ SwClient * pLast = aIter.GoStart(); +/*?*/ if( pLast ) // konnte zum Anfang gesprungen werden ?? +/*?*/ do { +/*?*/ pLast->Modify( pOld, pNew ); +/*?*/ } while( 0 != ( pLast = aIter++ )); +/*?*/ } +/*?*/ return; // das wars +/*?*/ +/*?*/ case RES_OBJECTDYING: +/*?*/ if( !GetDoc()->IsInDtor() && +/*?*/ ((SwPtrMsgPoolItem *)pOld)->pObject == (void*)GetRegisteredIn() ) +/*?*/ { +/*?*/ // mein Parent wird vernichtet, dann an den Parent vom Parent +/*?*/ // umhaengen und wieder aktualisieren +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwFrmFmt::Modify( pOld, pNew ); // erst umhaengen !!! +/*?*/ } +/*?*/ break; +/*N*/ +/*N*/ case RES_FMT_CHG: +/*N*/ if( !GetDoc()->IsInDtor() && +/*N*/ ((SwFmtChg*)pNew)->pChangedFmt == (void*)GetRegisteredIn() && +/*N*/ ((SwFmtChg*)pNew)->pChangedFmt->IsA( TYPE( SwSectionFmt )) ) +/*N*/ { +/*?*/ // mein Parent wird veraendert, muss mich aktualisieren +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwFrmFmt::Modify( pOld, pNew ); // erst umhaengen !!! +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ SwFrmFmt::Modify( pOld, pNew ); +/*N*/ } + + // erfrage vom Format Informationen + + + // alle Sections, die von dieser abgeleitet sind +/*N*/ USHORT SwSectionFmt::GetChildSections( SwSections& rArr, +/*N*/ SectionSort eSort, +/*N*/ int bAllSections ) const +/*N*/ { +/*N*/ rArr.Remove( 0, rArr.Count() ); +/*N*/ +/*N*/ if( GetDepends() ) +/*N*/ { +/*N*/ SwClientIter aIter( *(SwSectionFmt*)this ); +/*N*/ SwClient * pLast; +/*N*/ const SwNodeIndex* pIdx; +/*N*/ for( pLast = aIter.First(TYPE(SwSectionFmt)); pLast; pLast = aIter.Next() ) +/*N*/ if( bAllSections || +/*N*/ ( 0 != ( pIdx = ((SwSectionFmt*)pLast)->GetCntnt(FALSE). +/*N*/ GetCntntIdx()) && &pIdx->GetNodes() == &GetDoc()->GetNodes() )) +/*N*/ { +/*N*/ const SwSection* Dummy=((SwSectionFmt*)pLast)->GetSection(); +/*N*/ rArr.C40_INSERT( SwSection, +/*N*/ Dummy, +/*N*/ rArr.Count() ); +/*N*/ } +/*N*/ +/*N*/ // noch eine Sortierung erwuenscht ? +/*N*/ if( 1 < rArr.Count() ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 switch( eSort ) +/*N*/ } +/*N*/ return rArr.Count(); +/*N*/ } + + // erfrage, ob sich die Section im Nodes-Array oder UndoNodes-Array + // befindet. +/*N*/ int SwSectionFmt::IsInNodesArr() const +/*N*/ { +/*N*/ const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx(); +/*N*/ return pIdx && &pIdx->GetNodes() == &GetDoc()->GetNodes(); +/*N*/ } + + + + +/*N*/ SwSectionNode* SwSectionFmt::GetSectionNode( BOOL bAlways ) +/*N*/ { +/*N*/ const SwNodeIndex* pIdx = GetCntnt(FALSE).GetCntntIdx(); +/*N*/ if( pIdx && ( bAlways || &pIdx->GetNodes() == &GetDoc()->GetNodes() )) +/*N*/ return pIdx->GetNode().GetSectionNode(); +/*N*/ return 0; +/*N*/ } + + // ist die Section eine gueltige fuers GlobalDocument? +/*N*/ const SwSection* SwSectionFmt::GetGlobalDocSection() const +/*N*/ { +/*N*/ const SwSectionNode* pNd = GetSectionNode(); +/*N*/ if( pNd && +/*N*/ ( FILE_LINK_SECTION == pNd->GetSection().GetType() || +/*N*/ TOX_CONTENT_SECTION == pNd->GetSection().GetType() ) && +/*N*/ pNd->GetIndex() > pNd->GetNodes().GetEndOfExtras().GetIndex() && +/*N*/ !pNd->FindStartNode()->IsSectionNode() && +/*N*/ !pNd->FindStartNode()->FindSectionNode() ) +/*N*/ return &pNd->GetSection(); +/*N*/ return 0; +/*N*/ } + +/*N*/ void lcl_UpdateLinksInSect( SwBaseLink& rUpdLnk, SwSectionNode& rSectNd ) +/*N*/ { +/*N*/ SwDoc* pDoc = rSectNd.GetDoc(); +/*N*/ SwDocShell* pDShell = pDoc->GetDocShell(); +/*N*/ if( !pDShell || !pDShell->GetMedium() ) +/*?*/ return ; +/*N*/ +/*N*/ String sName( pDShell->GetMedium()->GetName() ); +/*N*/ SwBaseLink* pBLink; +/*N*/ String sMimeType( SotExchange::GetFormatMimeType( FORMAT_FILE )); +/*N*/ ::com::sun::star::uno::Any aValue; +/*N*/ aValue <<= ::rtl::OUString( sName ); // beliebiger Name +/*N*/ +/*N*/ const ::binfilter::SvBaseLinks& rLnks = pDoc->GetLinkManager().GetLinks(); +/*N*/ for( USHORT n = rLnks.Count(); n; ) +/*N*/ { +/*N*/ ::binfilter::SvBaseLink* pLnk = &(*rLnks[ --n ]); +/*N*/ if( pLnk && pLnk != &rUpdLnk && +/*N*/ OBJECT_CLIENT_FILE == pLnk->GetObjType() && +/*N*/ pLnk->ISA( SwBaseLink ) && +/*N*/ ( pBLink = (SwBaseLink*)pLnk )->IsInRange( rSectNd.GetIndex(), +/*N*/ rSectNd.EndOfSectionIndex() ) ) +/*N*/ { +/*?*/ // liegt in dem Bereich: also updaten. Aber nur wenns nicht +/*?*/ // im gleichen File liegt +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 String sFName; +/*N*/ } +/*N*/ } +/*N*/ } + + +// sucht sich die richtige DocShell raus oder erzeugt eine neue: +// Der Return-Wert gibt an, was mit der Shell zu geschehen hat: +// 0 - Fehler, konnte DocShell nicht finden +// 1 - DocShell ist ein existieren Document +// 2 - DocShell wurde neu angelegt, muss also wieder geschlossen werden + +/*N*/ int lcl_FindDocShell( SfxObjectShellRef& xDocSh, +/*N*/ const String& rFileName, +/*N*/ const String& rPasswd, +/*N*/ String& rFilter, +/*N*/ INT16 nVersion, +/*N*/ SwDocShell* pDestSh ) +/*N*/ { +/*N*/ if( !rFileName.Len() ) +/*?*/ return 0; +/*N*/ +/*N*/ // 1. existiert die Datei schon in der Liste aller Dokumente? +/*N*/ INetURLObject aTmpObj( rFileName ); +/*N*/ aTmpObj.SetMark( aEmptyStr ); +/*N*/ +/*N*/ // erstmal nur ueber die DocumentShells laufen und die mit dem +/*N*/ // Namen heraussuchen: +/*N*/ TypeId aType( TYPE(SwDocShell) ); +/*N*/ +/*N*/ SfxObjectShell* pShell = pDestSh; +/*N*/ BOOL bFirst = 0 != pShell; +/*N*/ +/*N*/ if( !bFirst ) +/*N*/ // keine DocShell uebergeben, also beginne mit der ersten aus der +/*N*/ // DocShell Liste +/*?*/ pShell = SfxObjectShell::GetFirst( &aType ); +/*N*/ +/*N*/ while( pShell ) +/*N*/ { +/*N*/ // die wollen wir haben +/*N*/ SfxMedium* pMed = pShell->GetMedium(); +/*N*/ if( pMed && pMed->GetURLObject() == aTmpObj ) +/*N*/ { +/*?*/ const SfxPoolItem* pItem; +/*?*/ if( ( SFX_ITEM_SET == pMed->GetItemSet()->GetItemState( +/*?*/ SID_VERSION, FALSE, &pItem ) ) +/*?*/ ? (nVersion == ((SfxInt16Item*)pItem)->GetValue()) +/*?*/ : !nVersion ) +/*?*/ { +/*?*/ // gefunden also returnen +/*?*/ xDocSh = pShell; +/*?*/ return 1; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ if( bFirst ) +/*N*/ { +/*N*/ bFirst = FALSE; +/*N*/ pShell = SfxObjectShell::GetFirst( &aType ); +/*N*/ } +/*N*/ else +/*?*/ pShell = SfxObjectShell::GetNext( *pShell, &aType ); +/*N*/ } +/*N*/ +/*N*/ // 2. selbst die Date oeffnen +/*N*/ SfxMedium* pMed = new SfxMedium( aTmpObj.GetMainURL( +/*N*/ INetURLObject::NO_DECODE ), STREAM_READ, TRUE ); +/*N*/ if( INET_PROT_FILE == aTmpObj.GetProtocol() ) +/*N*/ pMed->DownLoad(); // nur mal das Medium anfassen (DownLoaden) +/*N*/ +/*N*/ const SfxFilter* pSfxFlt = 0; +/*N*/ if( !pMed->GetError() ) +/*N*/ { +/*N*/ // kein Filter, dann suche ihn. Ansonsten teste, ob der angegebene +/*N*/ // ein gueltiger ist +/*N*/ if( rFilter.Len() ) +/*N*/ { +/*N*/ pSfxFlt = SwIoSystem::GetFilterOfFilterTxt( rFilter ); +/*N*/ if( pSfxFlt && !SwIoSystem::IsFileFilter( *pMed, pSfxFlt->GetUserData() ) && (pSfxFlt->GetFilterFlags() & SFX_FILTER_STARONEFILTER) == 0 ) +/*N*/ pSfxFlt = 0; // dann neu detecten lassen +/*N*/ } +/*N*/ +/*N*/ if( !pSfxFlt ) +/*N*/ pSfxFlt = SwIoSystem::GetFileFilter( pMed->GetPhysicalName(), aEmptyStr ); +/*N*/ +/*N*/ if( pSfxFlt ) +/*N*/ { +/*N*/ // ohne Filter geht gar nichts +/*N*/ pMed->SetFilter( pSfxFlt ); +/*N*/ +/*N*/ if( nVersion ) +/*?*/ pMed->GetItemSet()->Put( SfxInt16Item( SID_VERSION, nVersion )); +/*N*/ +/*N*/ if( rPasswd.Len() ) +/*?*/ pMed->GetItemSet()->Put( SfxStringItem( SID_PASSWORD, rPasswd )); +/*N*/ +/*N*/ xDocSh = new SwDocShell( SFX_CREATE_MODE_INTERNAL ); +/*N*/ if( xDocSh->DoLoad( pMed ) ) +/*N*/ return 2; +/*N*/ } +/*N*/ } +/*N*/ +/*?*/ if( !xDocSh.Is() ) // Medium muss noch geloescht werden +/*?*/ delete pMed; +/*?*/ +/*?*/ return 0; // das war wohl nichts +/*N*/ } + + +/*N*/ void SwIntrnlSectRefLink::DataChanged( const String& rMimeType, +/*N*/ const ::com::sun::star::uno::Any & rValue ) +/*N*/ { +/*N*/ SwSectionNode* pSectNd = rSectFmt.GetSectionNode( FALSE ); +/*N*/ SwDoc* pDoc = rSectFmt.GetDoc(); +/*N*/ +/*N*/ ULONG nDataFormat = SotExchange::GetFormatIdFromMimeType( rMimeType ); +/*N*/ +/*N*/ if( !pSectNd || !pDoc || pDoc->IsInDtor() || ChkNoDataFlag() || +/*N*/ SvxLinkManager::RegisterStatusInfoId() == nDataFormat ) +/*N*/ { +/*N*/ // sollten wir schon wieder im Undo stehen? +/*?*/ return ; +/*N*/ } +/*N*/ +/*N*/ // Undo immer abschalten +/*N*/ BOOL bWasVisibleLinks = pDoc->IsVisibleLinks(); +/*N*/ pDoc->SetVisibleLinks( FALSE ); +/*N*/ +/*N*/ SwPaM* pPam; +/*N*/ ViewShell* pVSh = 0; +/*N*/ SwEditShell* pESh = pDoc->GetEditShell( &pVSh ); +/*N*/ pDoc->LockExpFlds(); +/*N*/ { +/*N*/ // am Anfang des Bereichs einen leeren TextNode einfuegen +/*N*/ SwNodeIndex aIdx( *pSectNd, +1 ); +/*N*/ SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() ); +/*N*/ SwTxtNode* pNewNd = pDoc->GetNodes().MakeTxtNode( aIdx, +/*N*/ pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) ); +/*N*/ +/*N*/ if( pESh ) +/*N*/ pESh->StartAllAction(); +/*N*/ else if( pVSh ) +/*?*/ pVSh->StartAction(); +/*N*/ +/*N*/ SwPosition aPos( aIdx, SwIndex( pNewNd, 0 )); +/*N*/ aPos.nNode--; +/*N*/ pDoc->CorrAbs( aIdx, aEndIdx, aPos, TRUE ); +/*N*/ +/*N*/ pPam = new SwPaM( aPos ); +/*N*/ +/*N*/ //und alles dahinter liegende loeschen +/*N*/ aIdx--; +/*N*/ DelFlyInRange( aIdx, aEndIdx ); +/*N*/ _DelBookmarks( aIdx, aEndIdx ); +/*N*/ aIdx++; +/*N*/ +/*N*/ pDoc->GetNodes().Delete( aIdx, aEndIdx.GetIndex() - aIdx.GetIndex() ); +/*N*/ } +/*N*/ +/*N*/ SwSection& rSection = pSectNd->GetSection(); +/*N*/ rSection.SetConnectFlag( FALSE ); +/*N*/ +/*N*/ ::rtl::OUString sNewFileName; +/*N*/ Reader* pRead = 0; +/*N*/ switch( nDataFormat ) +/*N*/ { +/*N*/ case FORMAT_STRING: +/*?*/ pRead = ReadAscii; +/*?*/ break; +/*?*/ +/*?*/ case FORMAT_RTF: +/*?*/ pRead = ReadRtf; +/*?*/ break; +/*N*/ +/*N*/ case FORMAT_FILE: +/*N*/ if( rValue.hasValue() && ( rValue >>= sNewFileName ) ) +/*N*/ { +/*N*/ String sFilter, sRange, sFileName( sNewFileName ); +/*N*/ pDoc->GetLinkManager().GetDisplayNames( this, 0, &sFileName, +/*N*/ &sRange, &sFilter ); +/*N*/ +/*N*/ SwRedlineMode eOldRedlineMode = REDLINE_NONE; +/*N*/ SfxObjectShellRef xDocSh; +/*N*/ int nRet; +/*N*/ if( !sFileName.Len() ) +/*N*/ { +/*N*/ xDocSh = pDoc->GetDocShell(); +/*N*/ nRet = 1; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nRet = lcl_FindDocShell( xDocSh, sFileName, +/*N*/ rSection.GetLinkFilePassWd(), +/*N*/ sFilter, 0, pDoc->GetDocShell() ); +/*N*/ if( nRet ) +/*N*/ { +/*N*/ SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc(); +/*N*/ eOldRedlineMode = pSrcDoc->GetRedlineMode(); +/*N*/ pSrcDoc->SetRedlineMode( REDLINE_SHOW_INSERT ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( nRet ) +/*N*/ { +/*N*/ rSection.SetConnectFlag( TRUE ); +/*N*/ +/*N*/ SwNodeIndex aSave( pPam->GetPoint()->nNode, -1 ); +/*N*/ SwNodeRange* pCpyRg = 0; +/*N*/ +/*N*/ if( xDocSh->GetMedium() && +/*N*/ !rSection.GetLinkFilePassWd().Len() ) +/*N*/ { +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( SFX_ITEM_SET == xDocSh->GetMedium()->GetItemSet()-> +/*N*/ GetItemState( SID_PASSWORD, FALSE, &pItem ) ) +/*?*/ rSection.SetLinkFilePassWd( +/*?*/ ((SfxStringItem*)pItem)->GetValue() ); +/*N*/ } +/*N*/ +/*N*/ SwDoc* pSrcDoc = ((SwDocShell*)&xDocSh)->GetDoc(); +/*N*/ +/*N*/ if( sRange.Len() ) +/*N*/ { +/*N*/ // Rekursionen abfangen +/*N*/ BOOL bRecursion = FALSE; +/*N*/ if( pSrcDoc == pDoc ) +/*N*/ { +/*N*/ SwServerObjectRef refObj( (SwServerObject*) +/*N*/ pDoc->CreateLinkSource( sRange )); +/*N*/ if( refObj.Is() ) +/*N*/ { +/*N*/ bRecursion = refObj->IsLinkInServer( this ) || +/*N*/ ChkNoDataFlag(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwNodeIndex& rInsPos = pPam->GetPoint()->nNode; +/*N*/ +/*N*/ SwPaM* pCpyPam = 0; +/*N*/ if( !bRecursion && +/*N*/ pSrcDoc->SelectServerObj( sRange, pCpyPam, pCpyRg ) +/*N*/ && pCpyPam ) +/*N*/ { +/*?*/ if( pSrcDoc != pDoc || +/*?*/ pCpyPam->Start()->nNode > rInsPos || +/*?*/ rInsPos >= pCpyPam->End()->nNode ) +/*?*/ pSrcDoc->Copy( *pCpyPam, *pPam->GetPoint() ); +/*?*/ delete pCpyPam; +/*N*/ } +/*N*/ if( pCpyRg && pSrcDoc == pDoc && +/*N*/ pCpyRg->aStart < rInsPos && rInsPos < pCpyRg->aEnd ) +/*?*/ delete pCpyRg, pCpyRg = 0; +/*N*/ } +/*N*/ else if( pSrcDoc != pDoc ) +/*N*/ pCpyRg = new SwNodeRange( pSrcDoc->GetNodes().GetEndOfExtras(), 2, +/*N*/ pSrcDoc->GetNodes().GetEndOfContent() ); +/*N*/ +/*N*/ if( pCpyRg ) +/*N*/ { +/*N*/ SwNodeIndex& rInsPos = pPam->GetPoint()->nNode; +/*N*/ BOOL bCreateFrm = rInsPos.GetIndex() <= +/*N*/ pDoc->GetNodes().GetEndOfExtras().GetIndex() || +/*N*/ rInsPos.GetNode().FindTableNode(); +/*N*/ +/*N*/ SwTblNumFmtMerge aTNFM( *pSrcDoc, *pDoc ); +/*N*/ +/*N*/ pSrcDoc->CopyWithFlyInFly( *pCpyRg, rInsPos, bCreateFrm ); +/*N*/ aSave++; +/*N*/ +/*N*/ if( !bCreateFrm ) +/*N*/ ::binfilter::MakeFrms( pDoc, aSave, rInsPos ); +/*N*/ +/*N*/ // den letzten Node noch loeschen, aber nur wenn +/*N*/ // erfolgreich kopiert werden konnte, also der Bereich +/*N*/ // mehr als 1 Node enthaelt +/*N*/ if( 2 < pSectNd->EndOfSectionIndex() - pSectNd->GetIndex() ) +/*N*/ { +/*N*/ aSave = rInsPos; +/*N*/ pPam->Move( fnMoveBackward, fnGoNode ); +/*N*/ pPam->SetMark(); // beide SwPositions ummelden! +/*N*/ +/*N*/ pDoc->CorrAbs( aSave, *pPam->GetPoint(), 0, TRUE ); +/*N*/ pDoc->GetNodes().Delete( aSave, 1 ); +/*N*/ } +/*N*/ delete pCpyRg; +/*N*/ } +/*N*/ +/*N*/ // update alle Links in diesem Bereich +/*N*/ lcl_UpdateLinksInSect( *this, *pSectNd ); +/*N*/ } +/*N*/ if( xDocSh.Is() ) +/*N*/ { +/*N*/ if( 2 == nRet ) +/*N*/ xDocSh->DoClose(); +/*N*/ else if( ((SwDocShell*)&xDocSh)->GetDoc() ) +/*N*/ ((SwDocShell*)&xDocSh)->GetDoc()->SetRedlineMode( +/*N*/ eOldRedlineMode ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ // !!!! DDE nur updaten wenn Shell vorhanden ist?? +/*N*/ ::com::sun::star::uno::Sequence< sal_Int8 > aSeq; +/*N*/ if( pRead && rValue.hasValue() && ( rValue >>= aSeq ) ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( pESh ) +/*N*/ } +/*N*/ +/*N*/ +/*N*/ // Alle UndoActions entfernen und Undo wieder einschalten +/*N*/ pDoc->SetVisibleLinks( bWasVisibleLinks ); +/*N*/ +/*N*/ pDoc->UnlockExpFlds(); +/*N*/ if( !pDoc->IsExpFldsLocked() ) +/*N*/ pDoc->UpdateExpFlds(); +/*N*/ +/*N*/ if( pESh ) +/*N*/ pESh->EndAllAction(); +/*N*/ else if( pVSh ) +/*?*/ pVSh->EndAction(); +/*N*/ delete pPam; // wurde am Anfang angelegt +/*N*/ } + + + + +/*N*/ void SwSection::CreateLink( LinkCreateType eCreateType ) +/*N*/ { +/*N*/ SwSectionFmt* pFmt = GetFmt(); +/*N*/ if( !pFmt || CONTENT_SECTION == eType ) +/*?*/ return ; +/*N*/ +/*N*/ USHORT nUpdateType = ::binfilter::LINKUPDATE_ALWAYS; +/*N*/ +/*N*/ if( !refLink.Is() ) +/*N*/ // dann mal den BaseLink aufbauen +/*N*/ refLink = new SwIntrnlSectRefLink( *pFmt, nUpdateType, FORMAT_RTF ); +/*N*/ else +/*N*/ // sonst aus dem Linkmanager entfernen +/*?*/ pFmt->GetDoc()->GetLinkManager().Remove( refLink ); +/*N*/ +/*N*/ SwIntrnlSectRefLink* pLnk = (SwIntrnlSectRefLink*)&refLink; +/*N*/ +/*N*/ String sCmd( sLinkFileName ); +/*N*/ xub_StrLen nPos; +/*N*/ while( STRING_NOTFOUND != (nPos = sCmd.SearchAscii( " " )) ) +/*?*/ sCmd.Erase( nPos, 1 ); +/*N*/ +/*N*/ pLnk->SetUpdateMode( nUpdateType ); +/*N*/ pLnk->SetVisible( pFmt->GetDoc()->IsVisibleLinks() ); +/*N*/ +/*N*/ switch( eType ) +/*N*/ { +/*N*/ case DDE_LINK_SECTION: +/*?*/ pLnk->SetLinkSourceName( sCmd ); +/*?*/ pFmt->GetDoc()->GetLinkManager().InsertDDELink( pLnk ); +/*?*/ break; +/*N*/ case FILE_LINK_SECTION: +/*N*/ { +/*N*/ pLnk->SetContentType( FORMAT_FILE ); +/*N*/ String sFltr( sCmd.GetToken( 1, ::binfilter::cTokenSeperator ) ); +/*N*/ String sRange( sCmd.GetToken( 2, ::binfilter::cTokenSeperator ) ); +/*N*/ pFmt->GetDoc()->GetLinkManager().InsertFileLink( *pLnk, eType, +/*N*/ sCmd.GetToken( 0, ::binfilter::cTokenSeperator ), +/*N*/ ( sFltr.Len() ? &sFltr : 0 ), +/*N*/ ( sRange.Len() ? &sRange : 0 ) ); +/*N*/ } +/*N*/ break; +/*N*/ default: +/*?*/ ASSERT( !this, "Was ist das fuer ein Link?" ) +/*N*/ } +/*N*/ +/*N*/ switch( eCreateType ) +/*N*/ { +/*N*/ case CREATE_CONNECT: // Link gleich connecten +/*N*/ pLnk->Connect(); +/*N*/ break; +/*N*/ +/*N*/ case CREATE_UPDATE: // Link connecten und updaten +/*N*/ pLnk->Update(); +/*N*/ break; +/*N*/ } +/*N*/ } + + + +/*N*/ BOOL SwIntrnlSectRefLink::IsInRange( ULONG nSttNd, ULONG nEndNd, +/*N*/ xub_StrLen nStt, xub_StrLen nEnd ) const +/*N*/ { +/*N*/ SwStartNode* pSttNd = rSectFmt.GetSectionNode( FALSE ); +/*N*/ return pSttNd && +/*N*/ nSttNd < pSttNd->GetIndex() && +/*N*/ pSttNd->EndOfSectionIndex() < nEndNd; +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/docnode/sw_swbaslnk.cxx b/binfilter/bf_sw/source/core/docnode/sw_swbaslnk.cxx new file mode 100644 index 000000000000..39f769f714ce --- /dev/null +++ b/binfilter/bf_sw/source/core/docnode/sw_swbaslnk.cxx @@ -0,0 +1,478 @@ +/* -*- 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER + +#include <hintids.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> + +#include <bf_svx/boxitem.hxx> +#include <bf_svx/svxids.hrc> // fuer die EventIds +#include <bf_svx/linkmgr.hxx> + +#include <fmtfsize.hxx> +#include <fmtanchr.hxx> +#include <frmatr.hxx> +#include <frmfmt.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> + +#include <errhdl.hxx> + +#include <pam.hxx> +#include <editsh.hxx> +#include <swbaslnk.hxx> +#include <swserv.hxx> +#include <ndgrf.hxx> +#include <hints.hxx> +#include <cntfrm.hxx> +namespace binfilter { + +/*N*/ BOOL SetGrfFlySize( const Size& rGrfSz, const Size& rFrmSz, SwGrfNode* pGrfNd ); + +/*N*/ TYPEINIT1( SwBaseLink, ::binfilter::SvBaseLink ); + +/*N*/ SV_IMPL_REF( SwServerObject ) + +/*N*/ SwBaseLink::~SwBaseLink() +/*N*/ { +/*N*/ } + +/*N*/ void lcl_CallModify( SwGrfNode& rGrfNd, SfxPoolItem& rItem ) +/*N*/ { +/*N*/ //JP 4.7.2001: call fist all not SwNoTxtFrames, then the SwNoTxtFrames. +/*N*/ // The reason is, that in the SwNoTxtFrames the Graphic +/*N*/ // after a Paint will be swapped out! So all other "behind" +/*N*/ // them havent't a loaded Graphic. - #86501# +/*N*/ rGrfNd.LockModify(); +/*N*/ +/*N*/ SwClientIter aIter( rGrfNd ); +/*N*/ for( int n = 0; n < 2; ++n ) +/*N*/ { +/*N*/ SwClient * pLast = aIter.GoStart(); +/*N*/ if( pLast ) // konnte zum Anfang gesprungen werden ?? +/*N*/ { +/*N*/ do { +/*N*/ if( (0 == n) ^ ( 0 != pLast->ISA( SwCntntFrm )) ) +/*N*/ pLast->Modify( &rItem, &rItem ); +/*N*/ } while( 0 != ( pLast = aIter++ )); +/*N*/ } +/*N*/ } +/*N*/ rGrfNd.UnlockModify(); +/*N*/ } + + +/*N*/ void SwBaseLink::DataChanged( const String& rMimeType, +/*N*/ const ::com::sun::star::uno::Any & rValue ) +/*N*/ { +/*N*/ if( !pCntntNode ) +/*N*/ { +/*?*/ ASSERT(!this, "DataChanged ohne ContentNode" ); +/*?*/ return ; +/*N*/ } +/*N*/ +/*N*/ SwDoc* pDoc = pCntntNode->GetDoc(); +/*N*/ if( pDoc->IsInDtor() || ChkNoDataFlag() || bIgnoreDataChanged ) +/*N*/ { +/*?*/ bIgnoreDataChanged = FALSE; +/*?*/ return ; +/*N*/ } +/*N*/ +/*N*/ ULONG nFmt = SotExchange::GetFormatIdFromMimeType( rMimeType ); +/*N*/ +/*N*/ if( pCntntNode->IsNoTxtNode() && +/*N*/ nFmt == SvxLinkManager::RegisterStatusInfoId() ) +/*N*/ { +/*?*/ // nur eine Statusaenderung - Events bedienen ? +/*?*/ ::rtl::OUString sState; +/*?*/ if( rValue.hasValue() && ( rValue >>= sState )) +/*?*/ { +/*?*/ USHORT nEvent = 0; +/*?*/ switch( sState.toInt32() ) +/*?*/ { +/*?*/ case STATE_LOAD_OK: nEvent = SVX_EVENT_IMAGE_LOAD; break; +/*?*/ case STATE_LOAD_ERROR: nEvent = SVX_EVENT_IMAGE_ERROR; break; +/*?*/ case STATE_LOAD_ABORT: nEvent = SVX_EVENT_IMAGE_ABORT; break; +/*?*/ } +/*?*/ +/*?*/ SwFrmFmt* pFmt; +/*?*/ if( nEvent && 0 != ( pFmt = pCntntNode->GetFlyFmt() )) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwCallMouseEvent aCallEvent; +/*?*/ } +/*?*/ } +/*?*/ return; // das wars! +/*N*/ } +/*N*/ +/*N*/ FASTBOOL bUpdate = FALSE; +/*N*/ FASTBOOL bGraphicArrived = FALSE; +/*N*/ FASTBOOL bGraphicPieceArrived = FALSE; +/*N*/ FASTBOOL bDontNotify = FALSE; +/*N*/ Size aGrfSz, aFrmFmtSz; +/*N*/ +/*N*/ if( pCntntNode->IsGrfNode() ) +/*N*/ { +/*N*/ BfGraphicObject& rGrfObj = ((SwGrfNode*)pCntntNode)->GetGrfObj(); +/*N*/ +/*N*/ bDontNotify = ((SwGrfNode*)pCntntNode)->IsFrameInPaint(); +/*N*/ +/*N*/ bGraphicArrived = GetObj()->IsDataComplete(); +/*N*/ bGraphicPieceArrived = GetObj()->IsPending(); +/*N*/ ((SwGrfNode*)pCntntNode)->SetGrafikArrived( bGraphicArrived ); +/*N*/ +/*N*/ Graphic aGrf; +/*N*/ if( SvxLinkManager::GetGraphicFromAny( rMimeType, rValue, aGrf ) && +/*N*/ ( GRAPHIC_DEFAULT != aGrf.GetType() || +/*N*/ GRAPHIC_DEFAULT != rGrfObj.GetType() ) ) +/*N*/ { +/*N*/ aGrfSz = ::binfilter::GetGraphicSizeTwip( aGrf, 0 ); +/*N*/ if( static_cast< const SwGrfNode * >( pCntntNode )->IsChgTwipSizeFromPixel() ) +/*N*/ { +/*N*/ const MapMode aMapTwip( MAP_TWIP ); +/*N*/ aFrmFmtSz = +/*N*/ Application::GetDefaultDevice()->PixelToLogic( +/*N*/ aGrf.GetSizePixel(), aMapTwip ); +/*N*/ +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aFrmFmtSz = aGrfSz; +/*N*/ } +/*N*/ Size aSz( ((SwGrfNode*)pCntntNode)->GetTwipSize() ); +/*N*/ +/*N*/ if( bGraphicPieceArrived && GRAPHIC_DEFAULT != aGrf.GetType() && +/*N*/ ( !aSz.Width() || !aSz.Height() ) ) +/*N*/ { +/*N*/ // wenn nur ein Teil ankommt, aber die Groesse nicht +/*N*/ // gesetzt ist, dann muss "unten" der Teil von +/*N*/ // bGraphicArrived durchlaufen werden! +/*N*/ // (ansonten wird die Grafik in deft. Size gepaintet) +/*N*/ bGraphicArrived = TRUE; +/*N*/ bGraphicPieceArrived = FALSE; +/*N*/ } +/*N*/ +/*N*/ rGrfObj.SetGraphic( aGrf, rGrfObj.GetLink() ); +/*N*/ bUpdate = TRUE; +/*N*/ +/*N*/ // Bug 33999: damit der Node den Transparent-Status +/*N*/ // richtig gesetzt hat, ohne auf die Grafik +/*N*/ // zugreifen zu muessen (sonst erfolgt ein SwapIn!). +/*N*/ if( bGraphicArrived ) +/*N*/ { +/*N*/ // Bug #34735#: immer mit der korrekten Grafik-Size +/*N*/ // arbeiten +/*N*/ if( aGrfSz.Height() && aGrfSz.Width() && +/*N*/ aSz.Height() && aSz.Width() && +/*N*/ aGrfSz != aSz ) +/*?*/ ((SwGrfNode*)pCntntNode)->SetTwipSize( aGrfSz ); +/*N*/ } +/*N*/ } +/*N*/ if ( bUpdate && !bGraphicArrived && !bGraphicPieceArrived ) +/*?*/ ((SwGrfNode*)pCntntNode)->SetTwipSize( Size(0,0) ); +/*N*/ } +/*N*/ else if( pCntntNode->IsOLENode() ) +/*?*/ bUpdate = TRUE; +/*N*/ +/*N*/ ViewShell *pSh = 0; +/*N*/ SwEditShell* pESh = pDoc->GetEditShell( &pSh ); +/*N*/ +/*N*/ if ( bUpdate && bGraphicPieceArrived && !(bSwapIn || bDontNotify) ) +/*N*/ { +/*?*/ //Hint ohne Actions verschicken, loest direktes Paint aus. +/*?*/ if ( (!pSh || !pSh->ActionPend()) && (!pESh || !pESh->ActionPend()) ) +/*?*/ { +/*?*/ SwMsgPoolItem aMsgHint( RES_GRAPHIC_PIECE_ARRIVED ); +/*?*/ pCntntNode->Modify( &aMsgHint, &aMsgHint ); +/*?*/ bUpdate = FALSE; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ static BOOL bInNotifyLinks = FALSE; +/*N*/ if( bUpdate && !bDontNotify && (!bSwapIn || bGraphicArrived) && +/*N*/ !bInNotifyLinks) +/*N*/ { +/*N*/ BOOL bLockView = FALSE; +/*N*/ if( pSh ) +/*N*/ { +/*N*/ bLockView = pSh->IsViewLocked(); +/*N*/ pSh->LockView( TRUE ); +/*N*/ } +/*N*/ +/*N*/ if( pESh ) +/*N*/ pESh->StartAllAction(); +/*N*/ else if( pSh ) +/*?*/ pSh->StartAction(); +/*N*/ +/*N*/ SwMsgPoolItem aMsgHint( bGraphicArrived ? RES_GRAPHIC_ARRIVED : +/*N*/ RES_UPDATE_ATTR ); +/*N*/ +/*N*/ if ( bGraphicArrived ) +/*N*/ { +/*N*/ //Alle benachrichtigen, die am gleichen Link horchen. +/*N*/ bInNotifyLinks = TRUE; +/*N*/ +/*N*/ const ::binfilter::SvBaseLinks& rLnks = pDoc->GetLinkManager().GetLinks(); +/*N*/ for( USHORT n = rLnks.Count(); n; ) +/*N*/ { +/*N*/ ::binfilter::SvBaseLink* pLnk = &(*rLnks[ --n ]); +/*N*/ if( pLnk && OBJECT_CLIENT_GRF == pLnk->GetObjType() && +/*N*/ pLnk->ISA( SwBaseLink ) && pLnk->GetObj() == GetObj() ) +/*N*/ { +/*N*/ SwBaseLink* pBLink = (SwBaseLink*)pLnk; +/*N*/ SwGrfNode* pGrfNd = (SwGrfNode*)pBLink->pCntntNode; +/*N*/ +/*N*/ if( pBLink != this && +/*N*/ ( !bSwapIn || +/*N*/ GRAPHIC_DEFAULT == pGrfNd->GetGrfObj().GetType())) +/*N*/ { +/*?*/ pBLink->bIgnoreDataChanged = FALSE; +/*?*/ pBLink->DataChanged( rMimeType, rValue ); +/*?*/ pBLink->bIgnoreDataChanged = TRUE; +/*?*/ +/*?*/ pGrfNd->SetGrafikArrived( ((SwGrfNode*)pCntntNode)-> +/*?*/ IsGrafikArrived() ); +/*?*/ +/*?*/ // Fly der Grafik anpassen ! +/*?*/ if( !::binfilter::SetGrfFlySize( aGrfSz, aFrmFmtSz, pGrfNd ) ) +/*?*/ ::binfilter::lcl_CallModify( *pGrfNd, aMsgHint ); +/*N*/ } +/*N*/ else if( pBLink == this && +/*N*/ !::binfilter::SetGrfFlySize( aGrfSz, aFrmFmtSz, pGrfNd ) ) +/*N*/ // Fly der Grafik anpassen ! +/*N*/ ::binfilter::lcl_CallModify( *pGrfNd, aMsgHint ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ bInNotifyLinks = FALSE; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ pCntntNode->Modify( &aMsgHint, &aMsgHint ); +/*N*/ } +/*N*/ +/*N*/ +/*N*/ if( pESh ) +/*N*/ { +/*N*/ const BOOL bEndActionByVirDev = pESh->IsEndActionByVirDev(); +/*N*/ pESh->SetEndActionByVirDev( TRUE ); +/*N*/ pESh->EndAllAction(); +/*N*/ pESh->SetEndActionByVirDev( bEndActionByVirDev ); +/*N*/ } +/*N*/ else if( pSh ) +/*?*/ pSh->EndAction(); +/*N*/ +/*N*/ if( pSh && !bLockView ) +/*N*/ pSh->LockView( FALSE ); +/*N*/ } +/*N*/ } + +/*N*/ FASTBOOL SwBaseLink::IsShowQuickDrawBmp() const +/*N*/ { +/*N*/ return pCntntNode && pCntntNode->IsGrfNode() && +/*N*/ #ifdef NEW_GRFOBJ +/*N*/ ((SwGrfNode*)pCntntNode)->HasMagicId() +/*N*/ #else +/*N*/ // wie kommt man an die Info dran, das eine Grafik im Cache steht? +/*N*/ FALSE +/*N*/ #endif +/*N*/ ; +/*N*/ } + + +/*N*/ BOOL SetGrfFlySize( const Size& rGrfSz, const Size& rFrmSz, SwGrfNode* pGrfNd ) +/*N*/ { +/*N*/ BOOL bRet = FALSE; +/*N*/ ViewShell *pSh; +/*N*/ CurrShell *pCurr = 0; +/*N*/ if ( pGrfNd->GetDoc()->GetEditShell( &pSh ) ) +/*N*/ pCurr = new CurrShell( pSh ); +/*N*/ +/*N*/ Size aSz = pGrfNd->GetTwipSize(); +/*N*/ if ( !(aSz.Width() && aSz.Height()) && +/*N*/ rGrfSz.Width() && rGrfSz.Height() ) +/*N*/ { +/*N*/ SwFrmFmt* pFmt; +/*N*/ if( pGrfNd->IsChgTwipSize() && +/*N*/ 0 != (pFmt = pGrfNd->GetFlyFmt()) ) +/*N*/ { +/*?*/ Size aCalcSz( aSz ); +/*?*/ if ( !aSz.Height() && aSz.Width() ) +/*?*/ //passende Hoehe ausrechnen. +/*?*/ aCalcSz.Height() = rFrmSz.Height() * +/*?*/ aSz.Width() / rFrmSz.Width(); +/*?*/ else if ( !aSz.Width() && aSz.Height() ) +/*?*/ //passende Breite ausrechnen +/*?*/ aCalcSz.Width() = rFrmSz.Width() * +/*?*/ aSz.Height() / rFrmSz.Height(); +/*?*/ else +/*?*/ //Hoehe und Breite uebernehmen +/*?*/ aCalcSz = rFrmSz; +/*?*/ +/*?*/ const SvxBoxItem &rBox = pFmt->GetBox(); +/*?*/ aCalcSz.Width() += rBox.CalcLineSpace(BOX_LINE_LEFT) + +/*?*/ rBox.CalcLineSpace(BOX_LINE_RIGHT); +/*?*/ aCalcSz.Height()+= rBox.CalcLineSpace(BOX_LINE_TOP) + +/*?*/ rBox.CalcLineSpace(BOX_LINE_BOTTOM); +/*?*/ const SwFmtFrmSize& rOldAttr = pFmt->GetFrmSize(); +/*?*/ if( rOldAttr.GetSize() != aCalcSz ) +/*?*/ { +/*?*/ SwFmtFrmSize aAttr( rOldAttr ); +/*?*/ aAttr.SetSize( aCalcSz ); +/*?*/ pFmt->SetAttr( aAttr ); +/*?*/ bRet = TRUE; +/*?*/ } +/*?*/ +/*?*/ if( !aSz.Width() ) +/*?*/ { +/*?*/ // Wenn die Grafik in einer Tabelle verankert ist, muess +/*?*/ // die Tabellen-Spalten neu berechnet werden +/*?*/ const SwDoc *pDoc = pGrfNd->GetDoc(); +/*?*/ const SwPosition* pAPos = pFmt->GetAnchor().GetCntntAnchor(); +/*?*/ SwNode *pANd; +/*?*/ SwTableNode *pTblNd; +/*?*/ if( pAPos && +/*?*/ 0 != (pANd = pDoc->GetNodes()[pAPos->nNode]) && +/*?*/ 0 != (pTblNd = pANd->FindTableNode()) ) +/*?*/ { +/*?*/ BOOL bLastGrf = !pTblNd->GetTable().DecGrfsThatResize(); +/*?*/ SwHTMLTableLayout *pLayout = +/*?*/ pTblNd->GetTable().GetHTMLTableLayout(); +/*?*/ if( pLayout ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 USHORT nBrowseWidth = +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ // SetTwipSize skaliert ggf. eine ImageMap neu und +/*N*/ // braucht dazu das Frame-Format +/*N*/ pGrfNd->SetTwipSize( rGrfSz ); +/*N*/ } +/*N*/ +/*N*/ delete pCurr; +/*N*/ +/*N*/ return bRet; +/*N*/ } + +/*N*/ FASTBOOL SwBaseLink::SwapIn( BOOL bWaitForData, BOOL bNativFormat ) +/*N*/ { +/*N*/ bSwapIn = TRUE; +/*N*/ +/*N*/ FASTBOOL bRes; +/*N*/ +/*N*/ if( !GetObj() && ( bNativFormat || ( !IsSynchron() && bWaitForData ) )) +/*N*/ { +/*?*/ AddNextRef(); +/*?*/ _GetRealObject(); +/*?*/ ReleaseRef(); +/*N*/ } +/*N*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ { +/*N*/ String sGrfNm; +/*N*/ GetLinkManager()->GetDisplayNames( this, 0, &sGrfNm, 0, 0 ); +/*N*/ int x = 0; +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ if( GetObj() ) +/*N*/ { +/*N*/ String aMimeType( SotExchange::GetFormatMimeType( GetContentType() )); +/*N*/ +/*N*/ //!! ??? what have we here to do ???? +/*N*/ //!! if( bNativFormat ) +/*N*/ //!! aData.SetAspect( aData.GetAspect() | ASPECT_ICON ); +/*N*/ +/*N*/ ::com::sun::star::uno::Any aValue; +/*N*/ GetObj()->GetData( aValue, aMimeType, !IsSynchron() && bWaitForData ); +/*N*/ +/*N*/ if( bWaitForData && !GetObj() ) +/*N*/ { +/*?*/ ASSERT( !this, "das SvxFileObject wurde in einem GetData geloescht!" ); +/*?*/ bRes = FALSE; +/*N*/ } +/*N*/ else if( 0 != ( bRes = aValue.hasValue() ) ) +/*N*/ { +/*N*/ //JP 14.04.99: Bug 64820 - das Flag muss beim SwapIn natuerlich +/*N*/ // zurueckgesetzt werden. Die Daten sollen ja neu +/*N*/ // uebernommen werden +/*N*/ bIgnoreDataChanged = FALSE; +/*N*/ DataChanged( aMimeType, aValue ); +/*N*/ } +/*N*/ } +/*N*/ else if( !IsSynchron() && bWaitForData ) +/*N*/ { +/*?*/ SetSynchron( TRUE ); +/*?*/ bRes = Update(); +/*?*/ SetSynchron( FALSE ); +/*N*/ } +/*N*/ else +/*N*/ bRes = Update(); +/*N*/ +/*N*/ bSwapIn = FALSE; +/*N*/ return bRes; +/*N*/ } + + + +/*N*/ BOOL SwBaseLink::IsRecursion( const SwBaseLink* pChkLnk ) const +/*N*/ { +/*N*/ SwServerObjectRef aRef( (SwServerObject*)GetObj() ); +/*N*/ if( aRef.Is() ) +/*N*/ { +/*N*/ // es ist ein ServerObject, also frage nach allen darin +/*N*/ // befindlichen Links, ob wir darin enthalten sind. Ansonsten +/*N*/ // handelt es sich um eine Rekursion. +/*N*/ return aRef->IsLinkInServer( pChkLnk ); +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL SwBaseLink::IsInRange( ULONG, ULONG, xub_StrLen, xub_StrLen ) const +/*N*/ { +/*N*/ // Grafik oder OLE-Links nicht, +/*N*/ // Felder oder Sections haben eigene Ableitung! +/*N*/ return FALSE; +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |