diff options
Diffstat (limited to 'binfilter/bf_sw/source/core/docnode/sw_node2lay.cxx')
-rw-r--r-- | binfilter/bf_sw/source/core/docnode/sw_node2lay.cxx | 360 |
1 files changed, 360 insertions, 0 deletions
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: */ |