diff options
Diffstat (limited to 'sw/source/core/undo/undobj1.cxx')
-rw-r--r-- | sw/source/core/undo/undobj1.cxx | 729 |
1 files changed, 729 insertions, 0 deletions
diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx new file mode 100644 index 000000000000..49471cf4501f --- /dev/null +++ b/sw/source/core/undo/undobj1.cxx @@ -0,0 +1,729 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" + +#include <svl/itemiter.hxx> + +#include <hintids.hxx> +#include <hints.hxx> +#include <fmtflcnt.hxx> +#include <fmtanchr.hxx> +#include <fmtcntnt.hxx> +#include <txtflcnt.hxx> +#include <frmfmt.hxx> +#include <flyfrm.hxx> +#include <UndoCore.hxx> +#include <UndoDraw.hxx> +#include <rolbck.hxx> // fuer die Attribut History +#include <doc.hxx> +#include <docary.hxx> +#include <rootfrm.hxx> +#include <swundo.hxx> // fuer die UndoIds +#include <pam.hxx> +#include <ndtxt.hxx> +// OD 26.06.2003 #108784# +#include <dcontact.hxx> +#include <ndole.hxx> + + +//--------------------------------------------------------------------- +// SwUndoLayBase ///////////////////////////////////////////////////////// + +SwUndoFlyBase::SwUndoFlyBase( SwFrmFmt* pFormat, SwUndoId nUndoId ) + : SwUndo( nUndoId ), pFrmFmt( pFormat ) +{ +} + +SwUndoFlyBase::~SwUndoFlyBase() +{ + if( bDelFmt ) // loeschen waehrend eines Undo's ?? + delete pFrmFmt; +} + +void SwUndoFlyBase::InsFly(::sw::UndoRedoContext & rContext, bool bShowSelFrm) +{ + SwDoc *const pDoc = & rContext.GetDoc(); + + // ins Array wieder eintragen + SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts(); + rFlyFmts.Insert( pFrmFmt, rFlyFmts.Count() ); + + // OD 26.06.2003 #108784# - insert 'master' drawing object into drawing page + if ( RES_DRAWFRMFMT == pFrmFmt->Which() ) + { + SwDrawContact* pDrawContact = + static_cast<SwDrawContact*>(pFrmFmt->FindContactObj()); + if ( pDrawContact ) + { + pDrawContact->InsertMasterIntoDrawPage(); + // --> OD 2005-01-31 #i40845# - follow-up of #i35635# + // move object to visible layer + pDrawContact->MoveObjToVisibleLayer( pDrawContact->GetMaster() ); + // <-- + } + } + + SwFmtAnchor aAnchor( (RndStdIds)nRndId ); + + if (FLY_AT_PAGE == nRndId) + { + aAnchor.SetPageNum( (sal_uInt16)nNdPgPos ); + } + else + { + SwPosition aNewPos(pDoc->GetNodes().GetEndOfContent()); + aNewPos.nNode = nNdPgPos; + if ((FLY_AS_CHAR == nRndId) || (FLY_AT_CHAR == nRndId)) + { + aNewPos.nContent.Assign( aNewPos.nNode.GetNode().GetCntntNode(), + nCntPos ); + } + aAnchor.SetAnchor( &aNewPos ); + } + + pFrmFmt->SetFmtAttr( aAnchor ); // Anker neu setzen + + if( RES_DRAWFRMFMT != pFrmFmt->Which() ) + { + // Content holen und -Attribut neu setzen + SwNodeIndex aIdx( pDoc->GetNodes() ); + RestoreSection( pDoc, &aIdx, SwFlyStartNode ); + pFrmFmt->SetFmtAttr( SwFmtCntnt( aIdx.GetNode().GetStartNode() )); + } + + //JP 18.12.98: Bug 60505 - InCntntAttribut erst setzen, wenn der Inhalt + // vorhanden ist! Sonst wuerde das Layout den Fly vorher + // formatieren, aber keine Inhalt finden; so geschene bei + // Grafiken aus dem Internet + if (FLY_AS_CHAR == nRndId) + { + // es muss mindestens das Attribut im TextNode stehen + SwCntntNode* pCNd = aAnchor.GetCntntAnchor()->nNode.GetNode().GetCntntNode(); + OSL_ENSURE( pCNd->IsTxtNode(), "no Text Node at position." ); + SwFmtFlyCnt aFmt( pFrmFmt ); + static_cast<SwTxtNode*>(pCNd)->InsertItem( aFmt, nCntPos, nCntPos ); + } + + pFrmFmt->MakeFrms(); + + if( bShowSelFrm ) + { + rContext.SetSelections(pFrmFmt, 0); + } + + if( GetHistory() ) + GetHistory()->Rollback( pDoc ); + + switch( nRndId ) + { + case FLY_AS_CHAR: + case FLY_AT_CHAR: + { + const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); + nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex(); + nCntPos = rAnchor.GetCntntAnchor()->nContent.GetIndex(); + } + break; + case FLY_AT_PARA: + case FLY_AT_FLY: + { + const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); + nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex(); + } + break; + case FLY_AT_PAGE: + break; + } + bDelFmt = sal_False; +} + +void SwUndoFlyBase::DelFly( SwDoc* pDoc ) +{ + bDelFmt = sal_True; // im DTOR das Format loeschen + pFrmFmt->DelFrms(); // Frms vernichten. + + // alle Uno-Objecte sollten sich jetzt abmelden + { + SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFrmFmt ); + pFrmFmt->ModifyNotification( &aMsgHint, &aMsgHint ); + } + + if ( RES_DRAWFRMFMT != pFrmFmt->Which() ) + { + // gibt es ueberhaupt Inhalt, dann sicher diesen + const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); + OSL_ENSURE( rCntnt.GetCntntIdx(), "Fly ohne Inhalt" ); + + SaveSection( pDoc, *rCntnt.GetCntntIdx() ); + ((SwFmtCntnt&)rCntnt).SetNewCntntIdx( (const SwNodeIndex*)0 ); + } + // OD 02.07.2003 #108784# - remove 'master' drawing object from drawing page + else if ( RES_DRAWFRMFMT == pFrmFmt->Which() ) + { + SwDrawContact* pDrawContact = + static_cast<SwDrawContact*>(pFrmFmt->FindContactObj()); + if ( pDrawContact ) + { + pDrawContact->RemoveMasterFromDrawPage(); + } + } + + const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); + const SwPosition* pPos = rAnchor.GetCntntAnchor(); + // die Positionen im Nodes-Array haben sich verschoben + nRndId = static_cast<sal_uInt16>(rAnchor.GetAnchorId()); + if (FLY_AS_CHAR == nRndId) + { + nNdPgPos = pPos->nNode.GetIndex(); + nCntPos = pPos->nContent.GetIndex(); + SwTxtNode *const pTxtNd = pPos->nNode.GetNode().GetTxtNode(); + OSL_ENSURE( pTxtNd, "Kein Textnode gefunden" ); + SwTxtFlyCnt* const pAttr = static_cast<SwTxtFlyCnt*>( + pTxtNd->GetTxtAttrForCharAt( nCntPos, RES_TXTATR_FLYCNT ) ); + // Attribut steht noch im TextNode, loeschen + if( pAttr && pAttr->GetFlyCnt().GetFrmFmt() == pFrmFmt ) + { + // Pointer auf 0, nicht loeschen + ((SwFmtFlyCnt&)pAttr->GetFlyCnt()).SetFlyFmt(); + SwIndex aIdx( pPos->nContent ); + pTxtNd->EraseText( aIdx, 1 ); + } + } + else if (FLY_AT_CHAR == nRndId) + { + nNdPgPos = pPos->nNode.GetIndex(); + nCntPos = pPos->nContent.GetIndex(); + } + else if ((FLY_AT_PARA == nRndId) || (FLY_AT_FLY == nRndId)) + { + nNdPgPos = pPos->nNode.GetIndex(); + } + else + { + nNdPgPos = rAnchor.GetPageNum(); + } + + pFrmFmt->ResetFmtAttr( RES_ANCHOR ); // Anchor loeschen + + + // aus dem Array austragen + SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts(); + rFlyFmts.Remove( rFlyFmts.GetPos( pFrmFmt )); +} + +// SwUndoInsLayFmt /////////////////////////////////////////////////////// + +SwUndoInsLayFmt::SwUndoInsLayFmt( SwFrmFmt* pFormat, sal_uLong nNodeIdx, xub_StrLen nCntIdx ) + : SwUndoFlyBase( pFormat, RES_DRAWFRMFMT == pFormat->Which() ? + UNDO_INSDRAWFMT : UNDO_INSLAYFMT ), + mnCrsrSaveIndexPara( nNodeIdx ), mnCrsrSaveIndexPos( nCntIdx ) +{ + const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); + nRndId = static_cast<sal_uInt16>(rAnchor.GetAnchorId()); + bDelFmt = sal_False; + switch( nRndId ) + { + case FLY_AT_PAGE: + nNdPgPos = rAnchor.GetPageNum(); + break; + case FLY_AT_PARA: + case FLY_AT_FLY: + nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex(); + break; + case FLY_AS_CHAR: + case FLY_AT_CHAR: + { + const SwPosition* pPos = rAnchor.GetCntntAnchor(); + nCntPos = pPos->nContent.GetIndex(); + nNdPgPos = pPos->nNode.GetIndex(); + } + break; + default: + OSL_FAIL( "Was denn fuer ein FlyFrame?" ); + } +} + +SwUndoInsLayFmt::~SwUndoInsLayFmt() +{ +} + +void SwUndoInsLayFmt::UndoImpl(::sw::UndoRedoContext & rContext) +{ + SwDoc & rDoc(rContext.GetDoc()); + const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); + if( rCntnt.GetCntntIdx() ) // kein Inhalt + { + bool bRemoveIdx = true; + if( mnCrsrSaveIndexPara > 0 ) + { + SwTxtNode *const pNode = + rDoc.GetNodes()[mnCrsrSaveIndexPara]->GetTxtNode(); + if( pNode ) + { + SwNodeIndex aIdx( rDoc.GetNodes(), + rCntnt.GetCntntIdx()->GetIndex() ); + SwNodeIndex aEndIdx( rDoc.GetNodes(), + aIdx.GetNode().EndOfSectionIndex() ); + SwIndex aIndex( pNode, mnCrsrSaveIndexPos ); + SwPosition aPos( *pNode, aIndex ); + rDoc.CorrAbs( aIdx, aEndIdx, aPos, sal_True ); + bRemoveIdx = false; + } + } + if( bRemoveIdx ) + { + RemoveIdxFromSection( rDoc, rCntnt.GetCntntIdx()->GetIndex() ); + } + } + DelFly(& rDoc); +} + +void SwUndoInsLayFmt::RedoImpl(::sw::UndoRedoContext & rContext) +{ + InsFly(rContext); +} + +void SwUndoInsLayFmt::RepeatImpl(::sw::RepeatContext & rContext) +{ + SwDoc *const pDoc = & rContext.GetDoc(); + // erfrage und setze den Anker neu + SwFmtAnchor aAnchor( pFrmFmt->GetAnchor() ); + if ((FLY_AT_PARA == aAnchor.GetAnchorId()) || + (FLY_AT_CHAR == aAnchor.GetAnchorId()) || + (FLY_AS_CHAR == aAnchor.GetAnchorId())) + { + SwPosition aPos( *rContext.GetRepeatPaM().GetPoint() ); + if (FLY_AT_PARA == aAnchor.GetAnchorId()) + { + aPos.nContent.Assign( 0, 0 ); + } + aAnchor.SetAnchor( &aPos ); + } + else if( FLY_AT_FLY == aAnchor.GetAnchorId() ) + { + SwStartNode const*const pSttNd = + rContext.GetRepeatPaM().GetNode()->FindFlyStartNode(); + if( pSttNd ) + { + SwPosition aPos( *pSttNd ); + aAnchor.SetAnchor( &aPos ); + } + else + { + return ; + } + } + else if (FLY_AT_PAGE == aAnchor.GetAnchorId()) + { + aAnchor.SetPageNum( pDoc->GetCurrentLayout()->GetCurrPage( &rContext.GetRepeatPaM() )); + } + else { + OSL_FAIL( "was fuer ein Anker ist es denn nun?" ); + } + + SwFrmFmt* pFlyFmt = pDoc->CopyLayoutFmt( *pFrmFmt, aAnchor, true, true ); + (void) pFlyFmt; +//FIXME nobody ever did anything with this selection: +// rContext.SetSelections(pFlyFmt, 0); +} + +// #111827# +String SwUndoInsLayFmt::GetComment() const +{ + String aResult; + + // HACK: disable caching: + // the SfxUndoManager calls GetComment() too early: the pFrmFmt does not + // have a SwDrawContact yet, so it will fall back to SwUndo::GetComment(), + // which sets pComment to a wrong value. +// if (! pComment) + if (true) + { + /* + If frame format is present and has an SdrObject use the undo + comment of the SdrObject. Otherwise use the default comment. + */ + + bool bDone = false; + if (pFrmFmt) + { + const SdrObject * pSdrObj = pFrmFmt->FindSdrObject(); + if ( pSdrObj ) + { + aResult = SdrUndoNewObj::GetComment( *pSdrObj ); + bDone = true; + } + } + + if (! bDone) + aResult = SwUndo::GetComment(); + } + else + aResult = *pComment; + + return aResult; +} + +// SwUndoDelLayFmt /////////////////////////////////////////////////////// + +static SwUndoId +lcl_GetSwUndoId(SwFrmFmt *const pFrmFmt) +{ + if (RES_DRAWFRMFMT != pFrmFmt->Which()) + { + const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); + OSL_ENSURE( rCntnt.GetCntntIdx(), "Fly without content" ); + + SwNodeIndex firstNode(*rCntnt.GetCntntIdx(), 1); + SwNoTxtNode *const pNoTxtNode(firstNode.GetNode().GetNoTxtNode()); + if (pNoTxtNode && pNoTxtNode->IsGrfNode()) + { + return UNDO_DELGRF; + } + else if (pNoTxtNode && pNoTxtNode->IsOLENode()) + { + // surprisingly not UNDO_DELOLE, which does not seem to work + return UNDO_DELETE; + } + } + return UNDO_DELLAYFMT; +} + +SwUndoDelLayFmt::SwUndoDelLayFmt( SwFrmFmt* pFormat ) + : SwUndoFlyBase( pFormat, lcl_GetSwUndoId(pFormat) ) + , bShowSelFrm( sal_True ) +{ + SwDoc* pDoc = pFormat->GetDoc(); + DelFly( pDoc ); +} + +SwRewriter SwUndoDelLayFmt::GetRewriter() const +{ + SwRewriter aRewriter; + + SwDoc * pDoc = pFrmFmt->GetDoc(); + + if (pDoc) + { + SwNodeIndex* pIdx = GetMvSttIdx(); + if( 1 == GetMvNodeCnt() && pIdx) + { + SwNode *const pNd = & pIdx->GetNode(); + + if ( pNd->IsNoTxtNode() && pNd->IsOLENode()) + { + SwOLENode * pOLENd = pNd->GetOLENode(); + + aRewriter.AddRule(UNDO_ARG1, pOLENd->GetDescription()); + } + } + } + + return aRewriter; +} + +void SwUndoDelLayFmt::UndoImpl(::sw::UndoRedoContext & rContext) +{ + InsFly( rContext, bShowSelFrm ); +} + +void SwUndoDelLayFmt::RedoImpl(::sw::UndoRedoContext & rContext) +{ + SwDoc & rDoc(rContext.GetDoc()); + const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); + if( rCntnt.GetCntntIdx() ) // kein Inhalt + { + RemoveIdxFromSection(rDoc, rCntnt.GetCntntIdx()->GetIndex()); + } + + DelFly(& rDoc); +} + +void SwUndoDelLayFmt::RedoForRollback() +{ + const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); + if( rCntnt.GetCntntIdx() ) // kein Inhalt + RemoveIdxFromSection( *pFrmFmt->GetDoc(), + rCntnt.GetCntntIdx()->GetIndex() ); + + DelFly( pFrmFmt->GetDoc() ); +} + +// SwUndoSetFlyFmt /////////////////////////////////////////////////////// + +SwUndoSetFlyFmt::SwUndoSetFlyFmt( SwFrmFmt& rFlyFmt, SwFrmFmt& rNewFrmFmt ) + : SwUndo( UNDO_SETFLYFRMFMT ), SwClient( &rFlyFmt ), pFrmFmt( &rFlyFmt ), + pOldFmt( (SwFrmFmt*)rFlyFmt.DerivedFrom() ), pNewFmt( &rNewFrmFmt ), + pItemSet( new SfxItemSet( *rFlyFmt.GetAttrSet().GetPool(), + rFlyFmt.GetAttrSet().GetRanges() )), + nOldNode( 0 ), nNewNode( 0 ), + nOldCntnt( 0 ), nNewCntnt( 0 ), + nOldAnchorTyp( 0 ), nNewAnchorTyp( 0 ), bAnchorChgd( sal_False ) +{ +} + +SwRewriter SwUndoSetFlyFmt::GetRewriter() const +{ + SwRewriter aRewriter; + + if (pNewFmt) + aRewriter.AddRule(UNDO_ARG1, pNewFmt->GetName()); + + return aRewriter; +} + + +SwUndoSetFlyFmt::~SwUndoSetFlyFmt() +{ + delete pItemSet; +} + +void SwUndoSetFlyFmt::DeRegisterFromFormat( SwFmt& rFmt ) +{ + rFmt.Remove(this); +} + +void SwUndoSetFlyFmt::GetAnchor( SwFmtAnchor& rAnchor, + sal_uLong nNode, xub_StrLen nCntnt ) +{ + RndStdIds nAnchorTyp = rAnchor.GetAnchorId(); + if (FLY_AT_PAGE != nAnchorTyp) + { + SwNode* pNd = pFrmFmt->GetDoc()->GetNodes()[ nNode ]; + + if( FLY_AT_FLY == nAnchorTyp + ? ( !pNd->IsStartNode() || SwFlyStartNode != + ((SwStartNode*)pNd)->GetStartNodeType() ) + : !pNd->IsTxtNode() ) + { + pNd = 0; // invalid position + } + else + { + SwPosition aPos( *pNd ); + if ((FLY_AS_CHAR == nAnchorTyp) || + (FLY_AT_CHAR == nAnchorTyp)) + { + if ( nCntnt > static_cast<SwTxtNode*>(pNd)->GetTxt().Len() ) + { + pNd = 0; // invalid position + } + else + { + aPos.nContent.Assign(static_cast<SwTxtNode*>(pNd), nCntnt); + } + } + if ( pNd ) + { + rAnchor.SetAnchor( &aPos ); + } + } + + if( !pNd ) + { + // ungueltige Position - setze auf 1. Seite + rAnchor.SetType( FLY_AT_PAGE ); + rAnchor.SetPageNum( 1 ); + } + } + else + rAnchor.SetPageNum( nCntnt ); +} + +void SwUndoSetFlyFmt::UndoImpl(::sw::UndoRedoContext & rContext) +{ + SwDoc & rDoc = rContext.GetDoc(); + + // ist das neue Format noch vorhanden ?? + if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmtPtr)pOldFmt ) ) + { + if( bAnchorChgd ) + pFrmFmt->DelFrms(); + + if( pFrmFmt->DerivedFrom() != pOldFmt ) + pFrmFmt->SetDerivedFrom( pOldFmt ); + + SfxItemIter aIter( *pItemSet ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + while( pItem ) + { + if( IsInvalidItem( pItem )) + pFrmFmt->ResetFmtAttr( pItemSet->GetWhichByPos( + aIter.GetCurPos() )); + else + pFrmFmt->SetFmtAttr( *pItem ); + + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + + if( bAnchorChgd ) + { + const SwFmtAnchor& rOldAnch = pFrmFmt->GetAnchor(); + if (FLY_AS_CHAR == rOldAnch.GetAnchorId()) + { + // Bei InCntnt's wird es spannend: Das TxtAttribut muss + // vernichtet werden. Leider reisst dies neben den Frms + // auch noch das Format mit in sein Grab. Um dass zu + // unterbinden loesen wir vorher die Verbindung zwischen + // Attribut und Format. + const SwPosition *pPos = rOldAnch.GetCntntAnchor(); + SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode(); + OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." ); + const xub_StrLen nIdx = pPos->nContent.GetIndex(); + SwTxtAttr * pHnt = pTxtNode->GetTxtAttrForCharAt( + nIdx, RES_TXTATR_FLYCNT ); + OSL_ENSURE( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT, + "Missing FlyInCnt-Hint." ); + OSL_ENSURE( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFrmFmt, + "Wrong TxtFlyCnt-Hint." ); + const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt(); + + // Die Verbindung ist geloest, jetzt muss noch das Attribut + // vernichtet werden. + pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx ); + } + + // Anker umsetzen + SwFmtAnchor aNewAnchor( (RndStdIds) nOldAnchorTyp ); + GetAnchor( aNewAnchor, nOldNode, nOldCntnt ); + pFrmFmt->SetFmtAttr( aNewAnchor ); + + if (FLY_AS_CHAR == aNewAnchor.GetAnchorId()) + { + SwPosition* pPos = (SwPosition*)aNewAnchor.GetCntntAnchor(); + SwFmtFlyCnt aFmt( pFrmFmt ); + pPos->nNode.GetNode().GetTxtNode()->InsertItem( aFmt, + nOldCntnt, 0 ); + } + + pFrmFmt->MakeFrms(); + } + rContext.SetSelections(pFrmFmt, 0); + } +} + +void SwUndoSetFlyFmt::RedoImpl(::sw::UndoRedoContext & rContext) +{ + SwDoc & rDoc = rContext.GetDoc(); + + // ist das neue Format noch vorhanden ?? + if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmtPtr)pNewFmt ) ) + { + + if( bAnchorChgd ) + { + SwFmtAnchor aNewAnchor( (RndStdIds) nNewAnchorTyp ); + GetAnchor( aNewAnchor, nNewNode, nNewCntnt ); + SfxItemSet aSet( rDoc.GetAttrPool(), aFrmFmtSetRange ); + aSet.Put( aNewAnchor ); + rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, &aSet ); + } + else + rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, 0 ); + + rContext.SetSelections(pFrmFmt, 0); + } +} + +void SwUndoSetFlyFmt::PutAttr( sal_uInt16 nWhich, const SfxPoolItem* pItem ) +{ + if( pItem && pItem != GetDfltAttr( nWhich ) ) + { + // Sonderbehandlung fuer den Anchor + if( RES_ANCHOR == nWhich ) + { + // nur den 1. Ankerwechsel vermerken + OSL_ENSURE( !bAnchorChgd, "mehrfacher Ankerwechsel nicht erlaubt!" ); + + bAnchorChgd = sal_True; + + const SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem; + switch( nOldAnchorTyp = static_cast<sal_uInt16>(pAnchor->GetAnchorId()) ) + { + case FLY_AS_CHAR: + case FLY_AT_CHAR: + nOldCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex(); + case FLY_AT_PARA: + case FLY_AT_FLY: + nOldNode = pAnchor->GetCntntAnchor()->nNode.GetIndex(); + break; + + default: + nOldCntnt = pAnchor->GetPageNum(); + } + + pAnchor = (SwFmtAnchor*)&pFrmFmt->GetAnchor(); + switch( nNewAnchorTyp = static_cast<sal_uInt16>(pAnchor->GetAnchorId()) ) + { + case FLY_AS_CHAR: + case FLY_AT_CHAR: + nNewCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex(); + case FLY_AT_PARA: + case FLY_AT_FLY: + nNewNode = pAnchor->GetCntntAnchor()->nNode.GetIndex(); + break; + + default: + nNewCntnt = pAnchor->GetPageNum(); + } + } + else + pItemSet->Put( *pItem ); + } + else + pItemSet->InvalidateItem( nWhich ); +} + +void SwUndoSetFlyFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* ) +{ + if( pOld ) + { + sal_uInt16 nWhich = pOld->Which(); + + if( nWhich < POOLATTR_END ) + PutAttr( nWhich, pOld ); + else if( RES_ATTRSET_CHG == nWhich ) + { + SfxItemIter aIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + while( pItem ) + { + PutAttr( pItem->Which(), pItem ); + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |