merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / undo / undobj1.cxx
blobd9ce9b12a8768f4d93a79d6c7ccb469e2b64af98
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: undobj1.cxx,v $
10 * $Revision: 1.18 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
36 #include <svtools/itemiter.hxx>
37 #include <fmtflcnt.hxx>
38 #include <fmtanchr.hxx>
39 #include <fmtcntnt.hxx>
40 #include <txtflcnt.hxx>
41 #include <frmfmt.hxx>
42 #include <flyfrm.hxx>
43 #include <undobj.hxx>
44 #include <rolbck.hxx> // fuer die Attribut History
45 #include <doc.hxx>
46 #include <docary.hxx>
47 #include <rootfrm.hxx>
48 #include <swundo.hxx> // fuer die UndoIds
49 #include <pam.hxx>
50 #include <ndtxt.hxx>
51 // OD 26.06.2003 #108784#
52 #include <dcontact.hxx>
53 #include <ndole.hxx>
55 // Inline Methode vom UndoIter
56 inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }
58 //---------------------------------------------------------------------
60 SwUndoFlyBase::SwUndoFlyBase( SwFrmFmt* pFormat, SwUndoId nUndoId )
61 : SwUndo( nUndoId ), pFrmFmt( pFormat )
65 SwUndoFlyBase::~SwUndoFlyBase()
67 if( bDelFmt ) // loeschen waehrend eines Undo's ??
68 delete pFrmFmt;
71 void SwUndoFlyBase::InsFly( SwUndoIter& rUndoIter, BOOL bShowSelFrm )
73 SwDoc* pDoc = &rUndoIter.GetDoc();
75 // ins Array wieder eintragen
76 SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
77 rFlyFmts.Insert( pFrmFmt, rFlyFmts.Count() );
79 // OD 26.06.2003 #108784# - insert 'master' drawing object into drawing page
80 if ( RES_DRAWFRMFMT == pFrmFmt->Which() )
82 SwDrawContact* pDrawContact =
83 static_cast<SwDrawContact*>(pFrmFmt->FindContactObj());
84 if ( pDrawContact )
86 pDrawContact->InsertMasterIntoDrawPage();
87 // --> OD 2005-01-31 #i40845# - follow-up of #i35635#
88 // move object to visible layer
89 pDrawContact->MoveObjToVisibleLayer( pDrawContact->GetMaster() );
90 // <--
94 SwFmtAnchor aAnchor( (RndStdIds)nRndId );
96 if( FLY_PAGE == nRndId )
97 aAnchor.SetPageNum( (USHORT)nNdPgPos );
98 else
100 SwPosition aNewPos( *rUndoIter.pAktPam->GetPoint() );
101 aNewPos.nNode = nNdPgPos;
102 if( FLY_IN_CNTNT == nRndId || FLY_AUTO_CNTNT == nRndId )
103 aNewPos.nContent.Assign( aNewPos.nNode.GetNode().GetCntntNode(),
104 nCntPos );
105 aAnchor.SetAnchor( &aNewPos );
108 pFrmFmt->SetFmtAttr( aAnchor ); // Anker neu setzen
110 if( RES_DRAWFRMFMT != pFrmFmt->Which() )
112 // Content holen und -Attribut neu setzen
113 SwNodeIndex aIdx( pDoc->GetNodes() );
114 RestoreSection( pDoc, &aIdx, SwFlyStartNode );
115 pFrmFmt->SetFmtAttr( SwFmtCntnt( aIdx.GetNode().GetStartNode() ));
118 //JP 18.12.98: Bug 60505 - InCntntAttribut erst setzen, wenn der Inhalt
119 // vorhanden ist! Sonst wuerde das Layout den Fly vorher
120 // formatieren, aber keine Inhalt finden; so geschene bei
121 // Grafiken aus dem Internet
122 if( FLY_IN_CNTNT == nRndId )
124 // es muss mindestens das Attribut im TextNode stehen
125 SwCntntNode* pCNd = aAnchor.GetCntntAnchor()->nNode.GetNode().GetCntntNode();
126 ASSERT( pCNd->IsTxtNode(), "no Text Node at position." );
127 SwFmtFlyCnt aFmt( pFrmFmt );
128 static_cast<SwTxtNode*>(pCNd)->InsertItem( aFmt, nCntPos, nCntPos );
131 pFrmFmt->MakeFrms();
133 if( bShowSelFrm )
134 rUndoIter.pSelFmt = pFrmFmt;
136 if( GetHistory() )
137 GetHistory()->Rollback( pDoc );
139 switch( nRndId )
141 case FLY_IN_CNTNT:
142 case FLY_AUTO_CNTNT:
144 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
145 nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
146 nCntPos = rAnchor.GetCntntAnchor()->nContent.GetIndex();
148 break;
149 case FLY_AT_CNTNT:
150 case FLY_AT_FLY:
152 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
153 nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
155 break;
156 case FLY_PAGE:
157 break;
159 bDelFmt = FALSE;
162 void SwUndoFlyBase::DelFly( SwDoc* pDoc )
164 bDelFmt = TRUE; // im DTOR das Format loeschen
165 pFrmFmt->DelFrms(); // Frms vernichten.
167 // alle Uno-Objecte sollten sich jetzt abmelden
169 SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFrmFmt );
170 pFrmFmt->Modify( &aMsgHint, &aMsgHint );
173 if ( RES_DRAWFRMFMT != pFrmFmt->Which() )
175 // gibt es ueberhaupt Inhalt, dann sicher diesen
176 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
177 ASSERT( rCntnt.GetCntntIdx(), "Fly ohne Inhalt" );
179 SaveSection( pDoc, *rCntnt.GetCntntIdx() );
180 ((SwFmtCntnt&)rCntnt).SetNewCntntIdx( (const SwNodeIndex*)0 );
182 // OD 02.07.2003 #108784# - remove 'master' drawing object from drawing page
183 else if ( RES_DRAWFRMFMT == pFrmFmt->Which() )
185 SwDrawContact* pDrawContact =
186 static_cast<SwDrawContact*>(pFrmFmt->FindContactObj());
187 if ( pDrawContact )
189 pDrawContact->RemoveMasterFromDrawPage();
193 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
194 const SwPosition* pPos = rAnchor.GetCntntAnchor();
195 // die Positionen im Nodes-Array haben sich verschoben
196 if( FLY_IN_CNTNT == ( nRndId = static_cast<USHORT>(rAnchor.GetAnchorId()) ) )
198 nNdPgPos = pPos->nNode.GetIndex();
199 nCntPos = pPos->nContent.GetIndex();
200 SwTxtNode *pTxtNd = pDoc->GetNodes()[ pPos->nNode ]->GetTxtNode();
201 ASSERT( pTxtNd, "Kein Textnode gefunden" );
202 SwTxtFlyCnt* const pAttr = static_cast<SwTxtFlyCnt*>(
203 pTxtNd->GetTxtAttrForCharAt( nCntPos, RES_TXTATR_FLYCNT ) );
204 // Attribut steht noch im TextNode, loeschen
205 if( pAttr && pAttr->GetFlyCnt().GetFrmFmt() == pFrmFmt )
207 // Pointer auf 0, nicht loeschen
208 ((SwFmtFlyCnt&)pAttr->GetFlyCnt()).SetFlyFmt();
209 SwIndex aIdx( pPos->nContent );
210 pTxtNd->EraseText( aIdx, 1 );
213 else if( FLY_AUTO_CNTNT == nRndId )
215 nNdPgPos = pPos->nNode.GetIndex();
216 nCntPos = pPos->nContent.GetIndex();
218 else if( FLY_AT_CNTNT == nRndId || FLY_AT_FLY == nRndId )
219 nNdPgPos = pPos->nNode.GetIndex();
220 else
221 nNdPgPos = rAnchor.GetPageNum();
223 pFrmFmt->ResetFmtAttr( RES_ANCHOR ); // Anchor loeschen
226 // aus dem Array austragen
227 SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts();
228 rFlyFmts.Remove( rFlyFmts.GetPos( pFrmFmt ));
231 // ----- Undo-InsertFly ------
233 SwUndoInsLayFmt::SwUndoInsLayFmt( SwFrmFmt* pFormat, ULONG nNodeIdx, xub_StrLen nCntIdx )
234 : SwUndoFlyBase( pFormat, RES_DRAWFRMFMT == pFormat->Which() ?
235 UNDO_INSDRAWFMT : UNDO_INSLAYFMT ),
236 mnCrsrSaveIndexPara( nNodeIdx ), mnCrsrSaveIndexPos( nCntIdx )
238 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
239 nRndId = static_cast<USHORT>(rAnchor.GetAnchorId());
240 bDelFmt = FALSE;
241 switch( nRndId )
243 case FLY_PAGE:
244 nNdPgPos = rAnchor.GetPageNum();
245 break;
246 case FLY_AT_CNTNT:
247 case FLY_AT_FLY:
248 nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex();
249 break;
250 case FLY_IN_CNTNT:
251 case FLY_AUTO_CNTNT:
253 const SwPosition* pPos = rAnchor.GetCntntAnchor();
254 nCntPos = pPos->nContent.GetIndex();
255 nNdPgPos = pPos->nNode.GetIndex();
257 break;
258 default:
259 ASSERT( FALSE, "Was denn fuer ein FlyFrame?" );
263 SwUndoInsLayFmt::~SwUndoInsLayFmt()
267 void SwUndoInsLayFmt::Undo( SwUndoIter& rUndoIter )
269 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
270 if( rCntnt.GetCntntIdx() ) // kein Inhalt
272 bool bRemoveIdx = true;
273 if( mnCrsrSaveIndexPara > 0 )
275 SwTxtNode *pNode = rUndoIter.GetDoc().GetNodes()[mnCrsrSaveIndexPara]->GetTxtNode();
276 if( pNode )
278 SwNodeIndex aIdx( rUndoIter.GetDoc().GetNodes(), rCntnt.GetCntntIdx()->GetIndex() );
279 SwNodeIndex aEndIdx( rUndoIter.GetDoc().GetNodes(), aIdx.GetNode().EndOfSectionIndex() );
280 SwIndex aIndex( pNode, mnCrsrSaveIndexPos );
281 SwPosition aPos( *pNode, aIndex );
282 rUndoIter.GetDoc().CorrAbs( aIdx, aEndIdx, aPos, TRUE );
283 bRemoveIdx = false;
286 if( bRemoveIdx )
287 RemoveIdxFromSection( rUndoIter.GetDoc(),
288 rCntnt.GetCntntIdx()->GetIndex() );
290 DelFly( &rUndoIter.GetDoc() );
293 void SwUndoInsLayFmt::Redo( SwUndoIter& rUndoIter )
295 rUndoIter.pLastUndoObj = 0;
296 InsFly( rUndoIter );
299 void SwUndoInsLayFmt::Repeat( SwUndoIter& rUndoIter )
301 if( UNDO_INSLAYFMT == rUndoIter.GetLastUndoId() &&
302 pFrmFmt == ((SwUndoInsLayFmt*)rUndoIter.pLastUndoObj)->pFrmFmt )
303 return;
305 SwDoc* pDoc = &rUndoIter.GetDoc();
306 // erfrage und setze den Anker neu
307 SwFmtAnchor aAnchor( pFrmFmt->GetAnchor() );
308 if( FLY_AT_CNTNT == aAnchor.GetAnchorId() ||
309 FLY_AUTO_CNTNT == aAnchor.GetAnchorId() ||
310 FLY_IN_CNTNT == aAnchor.GetAnchorId() )
312 SwPosition aPos( *rUndoIter.pAktPam->GetPoint() );
313 if( FLY_AT_CNTNT == aAnchor.GetAnchorId() )
314 aPos.nContent.Assign( 0, 0 );
315 aAnchor.SetAnchor( &aPos );
317 else if( FLY_AT_FLY == aAnchor.GetAnchorId() )
319 const SwStartNode* pSttNd = rUndoIter.pAktPam->GetNode()->FindFlyStartNode();
320 if( pSttNd )
322 SwPosition aPos( *pSttNd );
323 aAnchor.SetAnchor( &aPos );
325 else
327 rUndoIter.pLastUndoObj = this;
328 return ;
331 else if( FLY_PAGE == aAnchor.GetAnchorId() )
333 aAnchor.SetPageNum( pDoc->GetRootFrm()->GetCurrPage(
334 rUndoIter.pAktPam ));
336 else {
337 ASSERT( FALSE, "was fuer ein Anker ist es denn nun?" );
340 SwFrmFmt* pFlyFmt = pDoc->CopyLayoutFmt( *pFrmFmt, aAnchor, true, true );
341 rUndoIter.pSelFmt = pFlyFmt;
343 rUndoIter.pLastUndoObj = this;
346 // #111827#
347 String SwUndoInsLayFmt::GetComment() const
349 String aResult;
351 if (! pComment)
354 If frame format is present and has an SdrObject use the undo
355 comment of the SdrObject. Otherwise use the default comment.
358 bool bDone = false;
359 if (pFrmFmt)
361 const SdrObject * pSdrObj = pFrmFmt->FindSdrObject();
362 if ( pSdrObj )
364 aResult = SdrUndoNewObj::GetComment( *pSdrObj );
365 bDone = true;
369 if (! bDone)
370 aResult = SwUndo::GetComment();
372 else
373 aResult = *pComment;
375 return aResult;
378 // ----- Undo-DeleteFly ------
380 SwUndoDelLayFmt::SwUndoDelLayFmt( SwFrmFmt* pFormat )
381 : SwUndoFlyBase( pFormat, UNDO_DELLAYFMT ), bShowSelFrm( TRUE )
383 SwDoc* pDoc = pFormat->GetDoc();
384 DelFly( pDoc );
386 SwNodeIndex* pIdx = GetMvSttIdx();
387 SwNode* pNd;
388 if( 1 == GetMvNodeCnt() && pIdx &&
389 ( pNd = (*pDoc->GetUndoNds())[ *pIdx ] )->IsNoTxtNode() )
391 // dann setze eine andere Undo-ID; Grafik oder OLE
392 if( pNd->IsGrfNode() )
393 SetId( UNDO_DELGRF );
394 else if( pNd->IsOLENode() )
396 SetId( UNDO_DELETE );
402 SwRewriter SwUndoDelLayFmt::GetRewriter() const
404 SwRewriter aRewriter;
406 SwDoc * pDoc = pFrmFmt->GetDoc();
408 if (pDoc)
410 SwNodeIndex* pIdx = GetMvSttIdx();
411 if( 1 == GetMvNodeCnt() && pIdx)
413 SwNode * pNd = (*pDoc->GetUndoNds())[ *pIdx ];
415 if ( pNd->IsNoTxtNode() && pNd->IsOLENode())
417 SwOLENode * pOLENd = pNd->GetOLENode();
419 aRewriter.AddRule(UNDO_ARG1, pOLENd->GetDescription());
424 return aRewriter;
427 void SwUndoDelLayFmt::Undo( SwUndoIter& rUndoIter )
429 InsFly( rUndoIter, bShowSelFrm );
432 void SwUndoDelLayFmt::Redo( SwUndoIter& rUndoIter )
434 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
435 if( rCntnt.GetCntntIdx() ) // kein Inhalt
436 RemoveIdxFromSection( rUndoIter.GetDoc(),
437 rCntnt.GetCntntIdx()->GetIndex() );
439 DelFly( &rUndoIter.GetDoc() );
442 void SwUndoDelLayFmt::Redo()
444 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
445 if( rCntnt.GetCntntIdx() ) // kein Inhalt
446 RemoveIdxFromSection( *pFrmFmt->GetDoc(),
447 rCntnt.GetCntntIdx()->GetIndex() );
449 DelFly( pFrmFmt->GetDoc() );
452 /* \f */
454 SwUndoSetFlyFmt::SwUndoSetFlyFmt( SwFrmFmt& rFlyFmt, SwFrmFmt& rNewFrmFmt )
455 : SwUndo( UNDO_SETFLYFRMFMT ), SwClient( &rFlyFmt ), pFrmFmt( &rFlyFmt ),
456 pOldFmt( (SwFrmFmt*)rFlyFmt.DerivedFrom() ), pNewFmt( &rNewFrmFmt ),
457 pItemSet( new SfxItemSet( *rFlyFmt.GetAttrSet().GetPool(),
458 rFlyFmt.GetAttrSet().GetRanges() )),
459 nOldNode( 0 ), nNewNode( 0 ),
460 nOldCntnt( 0 ), nNewCntnt( 0 ),
461 nOldAnchorTyp( 0 ), nNewAnchorTyp( 0 ), bAnchorChgd( FALSE )
465 SwRewriter SwUndoSetFlyFmt::GetRewriter() const
467 SwRewriter aRewriter;
469 if (pNewFmt)
470 aRewriter.AddRule(UNDO_ARG1, pNewFmt->GetName());
472 return aRewriter;
476 SwUndoSetFlyFmt::~SwUndoSetFlyFmt()
478 delete pItemSet;
481 void SwUndoSetFlyFmt::GetAnchor( SwFmtAnchor& rAnchor,
482 ULONG nNode, xub_StrLen nCntnt )
484 RndStdIds nAnchorTyp = rAnchor.GetAnchorId();
485 if( FLY_PAGE != nAnchorTyp )
487 SwNode* pNd = pFrmFmt->GetDoc()->GetNodes()[ nNode ];
489 if( FLY_AT_FLY == nAnchorTyp
490 ? ( !pNd->IsStartNode() || SwFlyStartNode !=
491 ((SwStartNode*)pNd)->GetStartNodeType() )
492 : !pNd->IsTxtNode() )
493 pNd = 0; // ungueltige Position
494 else
496 SwPosition aPos( *pNd );
497 if( FLY_IN_CNTNT == nAnchorTyp ||
498 FLY_AUTO_CNTNT == nAnchorTyp )
500 if( nCntnt > ((SwTxtNode*)pNd)->GetTxt().Len() )
501 pNd = 0; // ungueltige Position
502 else
503 aPos.nContent.Assign( (SwTxtNode*)pNd, nCntnt );
505 if( pNd )
506 rAnchor.SetAnchor( &aPos );
509 if( !pNd )
511 // ungueltige Position - setze auf 1. Seite
512 rAnchor.SetType( FLY_PAGE );
513 rAnchor.SetPageNum( 1 );
516 else
517 rAnchor.SetPageNum( nCntnt );
520 void SwUndoSetFlyFmt::Undo( SwUndoIter& rIter )
522 SwDoc& rDoc = rIter.GetDoc();
524 // ist das neue Format noch vorhanden ??
525 if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmtPtr)pOldFmt ) )
527 if( bAnchorChgd )
528 pFrmFmt->DelFrms();
530 if( pFrmFmt->DerivedFrom() != pOldFmt )
531 pFrmFmt->SetDerivedFrom( pOldFmt );
533 SfxItemIter aIter( *pItemSet );
534 const SfxPoolItem* pItem = aIter.GetCurItem();
535 while( pItem )
537 if( IsInvalidItem( pItem ))
538 pFrmFmt->ResetFmtAttr( pItemSet->GetWhichByPos(
539 aIter.GetCurPos() ));
540 else
541 pFrmFmt->SetFmtAttr( *pItem );
543 if( aIter.IsAtEnd() )
544 break;
545 pItem = aIter.NextItem();
548 if( bAnchorChgd )
550 const SwFmtAnchor& rOldAnch = pFrmFmt->GetAnchor();
551 if( FLY_IN_CNTNT == rOldAnch.GetAnchorId() )
553 // Bei InCntnt's wird es spannend: Das TxtAttribut muss
554 // vernichtet werden. Leider reisst dies neben den Frms
555 // auch noch das Format mit in sein Grab. Um dass zu
556 // unterbinden loesen wir vorher die Verbindung zwischen
557 // Attribut und Format.
558 const SwPosition *pPos = rOldAnch.GetCntntAnchor();
559 SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
560 ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
561 const xub_StrLen nIdx = pPos->nContent.GetIndex();
562 SwTxtAttr * pHnt = pTxtNode->GetTxtAttrForCharAt(
563 nIdx, RES_TXTATR_FLYCNT );
564 ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
565 "Missing FlyInCnt-Hint." );
566 ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFrmFmt,
567 "Wrong TxtFlyCnt-Hint." );
568 const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
570 // Die Verbindung ist geloest, jetzt muss noch das Attribut
571 // vernichtet werden.
572 pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
575 // Anker umsetzen
576 SwFmtAnchor aNewAnchor( (RndStdIds) nOldAnchorTyp );
577 GetAnchor( aNewAnchor, nOldNode, nOldCntnt );
578 pFrmFmt->SetFmtAttr( aNewAnchor );
580 if( FLY_IN_CNTNT == aNewAnchor.GetAnchorId() )
582 SwPosition* pPos = (SwPosition*)aNewAnchor.GetCntntAnchor();
583 SwFmtFlyCnt aFmt( pFrmFmt );
584 pPos->nNode.GetNode().GetTxtNode()->InsertItem( aFmt,
585 nOldCntnt, 0 );
588 pFrmFmt->MakeFrms();
590 rIter.pSelFmt = pFrmFmt;
594 void SwUndoSetFlyFmt::Redo( SwUndoIter& rIter )
596 SwDoc& rDoc = rIter.GetDoc();
598 // ist das neue Format noch vorhanden ??
599 if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmtPtr)pNewFmt ) )
602 if( bAnchorChgd )
604 SwFmtAnchor aNewAnchor( (RndStdIds) nNewAnchorTyp );
605 GetAnchor( aNewAnchor, nNewNode, nNewCntnt );
606 SfxItemSet aSet( rDoc.GetAttrPool(), aFrmFmtSetRange );
607 aSet.Put( aNewAnchor );
608 rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, &aSet );
610 else
611 rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, 0 );
613 rIter.pSelFmt = pFrmFmt;
617 void SwUndoSetFlyFmt::PutAttr( USHORT nWhich, const SfxPoolItem* pItem )
619 if( pItem && pItem != GetDfltAttr( nWhich ) )
621 // Sonderbehandlung fuer den Anchor
622 if( RES_ANCHOR == nWhich )
624 // nur den 1. Ankerwechsel vermerken
625 ASSERT( !bAnchorChgd, "mehrfacher Ankerwechsel nicht erlaubt!" );
627 bAnchorChgd = TRUE;
629 const SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem;
630 switch( nOldAnchorTyp = static_cast<USHORT>(pAnchor->GetAnchorId()) )
632 case FLY_IN_CNTNT:
633 case FLY_AUTO_CNTNT:
634 nOldCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex();
635 case FLY_AT_CNTNT:
636 case FLY_AT_FLY:
637 nOldNode = pAnchor->GetCntntAnchor()->nNode.GetIndex();
638 break;
640 default:
641 nOldCntnt = pAnchor->GetPageNum();
644 pAnchor = (SwFmtAnchor*)&pFrmFmt->GetAnchor();
645 switch( nNewAnchorTyp = static_cast<USHORT>(pAnchor->GetAnchorId()) )
647 case FLY_IN_CNTNT:
648 case FLY_AUTO_CNTNT:
649 nNewCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex();
650 case FLY_AT_CNTNT:
651 case FLY_AT_FLY:
652 nNewNode = pAnchor->GetCntntAnchor()->nNode.GetIndex();
653 break;
655 default:
656 nNewCntnt = pAnchor->GetPageNum();
659 else
660 pItemSet->Put( *pItem );
662 else
663 pItemSet->InvalidateItem( nWhich );
666 void SwUndoSetFlyFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* )
668 if( pOld )
670 USHORT nWhich = pOld->Which();
672 if( nWhich < POOLATTR_END )
673 PutAttr( nWhich, pOld );
674 else if( RES_ATTRSET_CHG == nWhich )
676 SfxItemIter aIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
677 const SfxPoolItem* pItem = aIter.GetCurItem();
678 while( pItem )
680 PutAttr( pItem->Which(), pItem );
681 if( aIter.IsAtEnd() )
682 break;
683 pItem = aIter.NextItem();