1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 #include <svl/itemiter.hxx> 28 29 #include <hintids.hxx> 30 #include <hints.hxx> 31 #include <fmtflcnt.hxx> 32 #include <fmtanchr.hxx> 33 #include <fmtcntnt.hxx> 34 #include <txtflcnt.hxx> 35 #include <frmfmt.hxx> 36 #include <flyfrm.hxx> 37 #include <UndoCore.hxx> 38 #include <UndoDraw.hxx> 39 #include <rolbck.hxx> // fuer die Attribut History 40 #include <doc.hxx> 41 #include <docary.hxx> 42 #include <rootfrm.hxx> 43 #include <swundo.hxx> // fuer die UndoIds 44 #include <pam.hxx> 45 #include <ndtxt.hxx> 46 // OD 26.06.2003 #108784# 47 #include <dcontact.hxx> 48 #include <ndole.hxx> 49 50 51 //--------------------------------------------------------------------- 52 // SwUndoLayBase ///////////////////////////////////////////////////////// 53 54 SwUndoFlyBase::SwUndoFlyBase( SwFrmFmt* pFormat, SwUndoId nUndoId ) 55 : SwUndo( nUndoId ), pFrmFmt( pFormat ) 56 { 57 } 58 59 SwUndoFlyBase::~SwUndoFlyBase() 60 { 61 if( bDelFmt ) // loeschen waehrend eines Undo's ?? 62 delete pFrmFmt; 63 } 64 65 void SwUndoFlyBase::InsFly(::sw::UndoRedoContext & rContext, bool bShowSelFrm) 66 { 67 SwDoc *const pDoc = & rContext.GetDoc(); 68 69 // ins Array wieder eintragen 70 SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts(); 71 rFlyFmts.Insert( pFrmFmt, rFlyFmts.Count() ); 72 73 // OD 26.06.2003 #108784# - insert 'master' drawing object into drawing page 74 if ( RES_DRAWFRMFMT == pFrmFmt->Which() ) 75 { 76 SwDrawContact* pDrawContact = 77 static_cast<SwDrawContact*>(pFrmFmt->FindContactObj()); 78 if ( pDrawContact ) 79 { 80 pDrawContact->InsertMasterIntoDrawPage(); 81 // --> OD 2005-01-31 #i40845# - follow-up of #i35635# 82 // move object to visible layer 83 pDrawContact->MoveObjToVisibleLayer( pDrawContact->GetMaster() ); 84 // <-- 85 } 86 } 87 88 SwFmtAnchor aAnchor( (RndStdIds)nRndId ); 89 90 if (FLY_AT_PAGE == nRndId) 91 { 92 aAnchor.SetPageNum( (sal_uInt16)nNdPgPos ); 93 } 94 else 95 { 96 SwPosition aNewPos(pDoc->GetNodes().GetEndOfContent()); 97 aNewPos.nNode = nNdPgPos; 98 if ((FLY_AS_CHAR == nRndId) || (FLY_AT_CHAR == nRndId)) 99 { 100 aNewPos.nContent.Assign( aNewPos.nNode.GetNode().GetCntntNode(), 101 nCntPos ); 102 } 103 aAnchor.SetAnchor( &aNewPos ); 104 } 105 106 pFrmFmt->SetFmtAttr( aAnchor ); // Anker neu setzen 107 108 if( RES_DRAWFRMFMT != pFrmFmt->Which() ) 109 { 110 // Content holen und -Attribut neu setzen 111 SwNodeIndex aIdx( pDoc->GetNodes() ); 112 RestoreSection( pDoc, &aIdx, SwFlyStartNode ); 113 pFrmFmt->SetFmtAttr( SwFmtCntnt( aIdx.GetNode().GetStartNode() )); 114 } 115 116 //JP 18.12.98: Bug 60505 - InCntntAttribut erst setzen, wenn der Inhalt 117 // vorhanden ist! Sonst wuerde das Layout den Fly vorher 118 // formatieren, aber keine Inhalt finden; so geschene bei 119 // Grafiken aus dem Internet 120 if (FLY_AS_CHAR == nRndId) 121 { 122 // es muss mindestens das Attribut im TextNode stehen 123 SwCntntNode* pCNd = aAnchor.GetCntntAnchor()->nNode.GetNode().GetCntntNode(); 124 ASSERT( pCNd->IsTxtNode(), "no Text Node at position." ); 125 SwFmtFlyCnt aFmt( pFrmFmt ); 126 static_cast<SwTxtNode*>(pCNd)->InsertItem( aFmt, nCntPos, nCntPos ); 127 } 128 129 pFrmFmt->MakeFrms(); 130 131 if( bShowSelFrm ) 132 { 133 rContext.SetSelections(pFrmFmt, 0); 134 } 135 136 if( GetHistory() ) 137 GetHistory()->Rollback( pDoc ); 138 139 switch( nRndId ) 140 { 141 case FLY_AS_CHAR: 142 case FLY_AT_CHAR: 143 { 144 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); 145 nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex(); 146 nCntPos = rAnchor.GetCntntAnchor()->nContent.GetIndex(); 147 } 148 break; 149 case FLY_AT_PARA: 150 case FLY_AT_FLY: 151 { 152 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); 153 nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex(); 154 } 155 break; 156 case FLY_AT_PAGE: 157 break; 158 } 159 bDelFmt = sal_False; 160 } 161 162 void SwUndoFlyBase::DelFly( SwDoc* pDoc ) 163 { 164 bDelFmt = sal_True; // im DTOR das Format loeschen 165 pFrmFmt->DelFrms(); // Frms vernichten. 166 167 // alle Uno-Objecte sollten sich jetzt abmelden 168 { 169 SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, pFrmFmt ); 170 pFrmFmt->ModifyNotification( &aMsgHint, &aMsgHint ); 171 } 172 173 if ( RES_DRAWFRMFMT != pFrmFmt->Which() ) 174 { 175 // gibt es ueberhaupt Inhalt, dann sicher diesen 176 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); 177 ASSERT( rCntnt.GetCntntIdx(), "Fly ohne Inhalt" ); 178 179 SaveSection( pDoc, *rCntnt.GetCntntIdx() ); 180 ((SwFmtCntnt&)rCntnt).SetNewCntntIdx( (const SwNodeIndex*)0 ); 181 } 182 // OD 02.07.2003 #108784# - remove 'master' drawing object from drawing page 183 else if ( RES_DRAWFRMFMT == pFrmFmt->Which() ) 184 { 185 SwDrawContact* pDrawContact = 186 static_cast<SwDrawContact*>(pFrmFmt->FindContactObj()); 187 if ( pDrawContact ) 188 { 189 pDrawContact->RemoveMasterFromDrawPage(); 190 } 191 } 192 193 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); 194 const SwPosition* pPos = rAnchor.GetCntntAnchor(); 195 // die Positionen im Nodes-Array haben sich verschoben 196 nRndId = static_cast<sal_uInt16>(rAnchor.GetAnchorId()); 197 if (FLY_AS_CHAR == nRndId) 198 { 199 nNdPgPos = pPos->nNode.GetIndex(); 200 nCntPos = pPos->nContent.GetIndex(); 201 SwTxtNode *const pTxtNd = pPos->nNode.GetNode().GetTxtNode(); 202 OSL_ENSURE(pTxtNd, "no Textnode"); 203 SwTxtFlyCnt* const pAttr = static_cast<SwTxtFlyCnt*>( 204 pTxtNd->GetTxtAttrForCharAt( nCntPos, RES_TXTATR_FLYCNT ) ); 205 // Attribut steht noch im TextNode, loeschen 206 if( pAttr && pAttr->GetFlyCnt().GetFrmFmt() == pFrmFmt ) 207 { 208 // Pointer auf 0, nicht loeschen 209 ((SwFmtFlyCnt&)pAttr->GetFlyCnt()).SetFlyFmt(); 210 SwIndex aIdx( pPos->nContent ); 211 pTxtNd->EraseText( aIdx, 1 ); 212 } 213 } 214 else if (FLY_AT_CHAR == nRndId) 215 { 216 nNdPgPos = pPos->nNode.GetIndex(); 217 nCntPos = pPos->nContent.GetIndex(); 218 } 219 else if ((FLY_AT_PARA == nRndId) || (FLY_AT_FLY == nRndId)) 220 { 221 nNdPgPos = pPos->nNode.GetIndex(); 222 } 223 else 224 { 225 nNdPgPos = rAnchor.GetPageNum(); 226 } 227 228 pFrmFmt->ResetFmtAttr( RES_ANCHOR ); // Anchor loeschen 229 230 231 // aus dem Array austragen 232 SwSpzFrmFmts& rFlyFmts = *(SwSpzFrmFmts*)pDoc->GetSpzFrmFmts(); 233 rFlyFmts.Remove( rFlyFmts.GetPos( pFrmFmt )); 234 } 235 236 // SwUndoInsLayFmt /////////////////////////////////////////////////////// 237 238 SwUndoInsLayFmt::SwUndoInsLayFmt( SwFrmFmt* pFormat, sal_uLong nNodeIdx, xub_StrLen nCntIdx ) 239 : SwUndoFlyBase( pFormat, RES_DRAWFRMFMT == pFormat->Which() ? 240 UNDO_INSDRAWFMT : UNDO_INSLAYFMT ), 241 mnCrsrSaveIndexPara( nNodeIdx ), mnCrsrSaveIndexPos( nCntIdx ) 242 { 243 const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); 244 nRndId = static_cast<sal_uInt16>(rAnchor.GetAnchorId()); 245 bDelFmt = sal_False; 246 switch( nRndId ) 247 { 248 case FLY_AT_PAGE: 249 nNdPgPos = rAnchor.GetPageNum(); 250 break; 251 case FLY_AT_PARA: 252 case FLY_AT_FLY: 253 nNdPgPos = rAnchor.GetCntntAnchor()->nNode.GetIndex(); 254 break; 255 case FLY_AS_CHAR: 256 case FLY_AT_CHAR: 257 { 258 const SwPosition* pPos = rAnchor.GetCntntAnchor(); 259 nCntPos = pPos->nContent.GetIndex(); 260 nNdPgPos = pPos->nNode.GetIndex(); 261 } 262 break; 263 default: 264 ASSERT( sal_False, "Was denn fuer ein FlyFrame?" ); 265 } 266 } 267 268 SwUndoInsLayFmt::~SwUndoInsLayFmt() 269 { 270 } 271 272 void SwUndoInsLayFmt::UndoImpl(::sw::UndoRedoContext & rContext) 273 { 274 SwDoc & rDoc(rContext.GetDoc()); 275 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); 276 if( rCntnt.GetCntntIdx() ) // kein Inhalt 277 { 278 bool bRemoveIdx = true; 279 if( mnCrsrSaveIndexPara > 0 ) 280 { 281 SwTxtNode *const pNode = 282 rDoc.GetNodes()[mnCrsrSaveIndexPara]->GetTxtNode(); 283 if( pNode ) 284 { 285 SwNodeIndex aIdx( rDoc.GetNodes(), 286 rCntnt.GetCntntIdx()->GetIndex() ); 287 SwNodeIndex aEndIdx( rDoc.GetNodes(), 288 aIdx.GetNode().EndOfSectionIndex() ); 289 SwIndex aIndex( pNode, mnCrsrSaveIndexPos ); 290 SwPosition aPos( *pNode, aIndex ); 291 rDoc.CorrAbs( aIdx, aEndIdx, aPos, sal_True ); 292 bRemoveIdx = false; 293 } 294 } 295 if( bRemoveIdx ) 296 { 297 RemoveIdxFromSection( rDoc, rCntnt.GetCntntIdx()->GetIndex() ); 298 } 299 } 300 DelFly(& rDoc); 301 } 302 303 void SwUndoInsLayFmt::RedoImpl(::sw::UndoRedoContext & rContext) 304 { 305 InsFly(rContext); 306 } 307 308 void SwUndoInsLayFmt::RepeatImpl(::sw::RepeatContext & rContext) 309 { 310 SwDoc *const pDoc = & rContext.GetDoc(); 311 // erfrage und setze den Anker neu 312 SwFmtAnchor aAnchor( pFrmFmt->GetAnchor() ); 313 if ((FLY_AT_PARA == aAnchor.GetAnchorId()) || 314 (FLY_AT_CHAR == aAnchor.GetAnchorId()) || 315 (FLY_AS_CHAR == aAnchor.GetAnchorId())) 316 { 317 SwPosition aPos( *rContext.GetRepeatPaM().GetPoint() ); 318 if (FLY_AT_PARA == aAnchor.GetAnchorId()) 319 { 320 aPos.nContent.Assign( 0, 0 ); 321 } 322 aAnchor.SetAnchor( &aPos ); 323 } 324 else if( FLY_AT_FLY == aAnchor.GetAnchorId() ) 325 { 326 SwStartNode const*const pSttNd = 327 rContext.GetRepeatPaM().GetNode()->FindFlyStartNode(); 328 if( pSttNd ) 329 { 330 SwPosition aPos( *pSttNd ); 331 aAnchor.SetAnchor( &aPos ); 332 } 333 else 334 { 335 return ; 336 } 337 } 338 else if (FLY_AT_PAGE == aAnchor.GetAnchorId()) 339 { 340 aAnchor.SetPageNum( pDoc->GetCurrentLayout()->GetCurrPage( &rContext.GetRepeatPaM() )); 341 } 342 else { 343 ASSERT( sal_False, "was fuer ein Anker ist es denn nun?" ); 344 } 345 346 SwFrmFmt* pFlyFmt = pDoc->CopyLayoutFmt( *pFrmFmt, aAnchor, true, true ); 347 (void) pFlyFmt; 348 //FIXME nobody ever did anything with this selection: 349 // rContext.SetSelections(pFlyFmt, 0); 350 } 351 352 // #111827# 353 String SwUndoInsLayFmt::GetComment() const 354 { 355 String aResult; 356 357 // HACK: disable caching: 358 // the SfxUndoManager calls GetComment() too early: the pFrmFmt does not 359 // have a SwDrawContact yet, so it will fall back to SwUndo::GetComment(), 360 // which sets pComment to a wrong value. 361 // if (! pComment) 362 if (true) 363 { 364 /* 365 If frame format is present and has an SdrObject use the undo 366 comment of the SdrObject. Otherwise use the default comment. 367 */ 368 369 bool bDone = false; 370 if (pFrmFmt) 371 { 372 const SdrObject * pSdrObj = pFrmFmt->FindSdrObject(); 373 if ( pSdrObj ) 374 { 375 aResult = SdrUndoNewObj::GetComment( *pSdrObj ); 376 bDone = true; 377 } 378 } 379 380 if (! bDone) 381 aResult = SwUndo::GetComment(); 382 } 383 else 384 aResult = *pComment; 385 386 return aResult; 387 } 388 389 // SwUndoDelLayFmt /////////////////////////////////////////////////////// 390 391 static SwUndoId 392 lcl_GetSwUndoId(SwFrmFmt *const pFrmFmt) 393 { 394 if (RES_DRAWFRMFMT != pFrmFmt->Which()) 395 { 396 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); 397 OSL_ENSURE( rCntnt.GetCntntIdx(), "Fly without content" ); 398 399 SwNodeIndex firstNode(*rCntnt.GetCntntIdx(), 1); 400 SwNoTxtNode *const pNoTxtNode(firstNode.GetNode().GetNoTxtNode()); 401 if (pNoTxtNode && pNoTxtNode->IsGrfNode()) 402 { 403 return UNDO_DELGRF; 404 } 405 else if (pNoTxtNode && pNoTxtNode->IsOLENode()) 406 { 407 // surprisingly not UNDO_DELOLE, which does not seem to work 408 return UNDO_DELETE; 409 } 410 } 411 return UNDO_DELLAYFMT; 412 } 413 414 SwUndoDelLayFmt::SwUndoDelLayFmt( SwFrmFmt* pFormat ) 415 : SwUndoFlyBase( pFormat, lcl_GetSwUndoId(pFormat) ) 416 , bShowSelFrm( sal_True ) 417 { 418 SwDoc* pDoc = pFormat->GetDoc(); 419 DelFly( pDoc ); 420 } 421 422 SwRewriter SwUndoDelLayFmt::GetRewriter() const 423 { 424 SwRewriter aRewriter; 425 426 SwDoc * pDoc = pFrmFmt->GetDoc(); 427 428 if (pDoc) 429 { 430 SwNodeIndex* pIdx = GetMvSttIdx(); 431 if( 1 == GetMvNodeCnt() && pIdx) 432 { 433 SwNode *const pNd = & pIdx->GetNode(); 434 435 if ( pNd->IsNoTxtNode() && pNd->IsOLENode()) 436 { 437 SwOLENode * pOLENd = pNd->GetOLENode(); 438 439 aRewriter.AddRule(UNDO_ARG1, pOLENd->GetDescription()); 440 } 441 } 442 } 443 444 return aRewriter; 445 } 446 447 void SwUndoDelLayFmt::UndoImpl(::sw::UndoRedoContext & rContext) 448 { 449 InsFly( rContext, bShowSelFrm ); 450 } 451 452 void SwUndoDelLayFmt::RedoImpl(::sw::UndoRedoContext & rContext) 453 { 454 SwDoc & rDoc(rContext.GetDoc()); 455 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); 456 if( rCntnt.GetCntntIdx() ) // kein Inhalt 457 { 458 RemoveIdxFromSection(rDoc, rCntnt.GetCntntIdx()->GetIndex()); 459 } 460 461 DelFly(& rDoc); 462 } 463 464 void SwUndoDelLayFmt::RedoForRollback() 465 { 466 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); 467 if( rCntnt.GetCntntIdx() ) // kein Inhalt 468 RemoveIdxFromSection( *pFrmFmt->GetDoc(), 469 rCntnt.GetCntntIdx()->GetIndex() ); 470 471 DelFly( pFrmFmt->GetDoc() ); 472 } 473 474 // SwUndoSetFlyFmt /////////////////////////////////////////////////////// 475 476 SwUndoSetFlyFmt::SwUndoSetFlyFmt( SwFrmFmt& rFlyFmt, SwFrmFmt& rNewFrmFmt ) 477 : SwUndo( UNDO_SETFLYFRMFMT ), SwClient( &rFlyFmt ), pFrmFmt( &rFlyFmt ), 478 pOldFmt( (SwFrmFmt*)rFlyFmt.DerivedFrom() ), pNewFmt( &rNewFrmFmt ), 479 pItemSet( new SfxItemSet( *rFlyFmt.GetAttrSet().GetPool(), 480 rFlyFmt.GetAttrSet().GetRanges() )), 481 nOldNode( 0 ), nNewNode( 0 ), 482 nOldCntnt( 0 ), nNewCntnt( 0 ), 483 nOldAnchorTyp( 0 ), nNewAnchorTyp( 0 ), bAnchorChgd( sal_False ) 484 { 485 } 486 487 SwRewriter SwUndoSetFlyFmt::GetRewriter() const 488 { 489 SwRewriter aRewriter; 490 491 if (pNewFmt) 492 aRewriter.AddRule(UNDO_ARG1, pNewFmt->GetName()); 493 494 return aRewriter; 495 } 496 497 498 SwUndoSetFlyFmt::~SwUndoSetFlyFmt() 499 { 500 delete pItemSet; 501 } 502 503 void SwUndoSetFlyFmt::DeRegisterFromFormat( SwFmt& rFmt ) 504 { 505 rFmt.Remove(this); 506 } 507 508 void SwUndoSetFlyFmt::GetAnchor( SwFmtAnchor& rAnchor, 509 sal_uLong nNode, xub_StrLen nCntnt ) 510 { 511 RndStdIds nAnchorTyp = rAnchor.GetAnchorId(); 512 if (FLY_AT_PAGE != nAnchorTyp) 513 { 514 SwNode* pNd = pFrmFmt->GetDoc()->GetNodes()[ nNode ]; 515 516 if( FLY_AT_FLY == nAnchorTyp 517 ? ( !pNd->IsStartNode() || SwFlyStartNode != 518 ((SwStartNode*)pNd)->GetStartNodeType() ) 519 : !pNd->IsTxtNode() ) 520 { 521 pNd = 0; // invalid position 522 } 523 else 524 { 525 SwPosition aPos( *pNd ); 526 if ((FLY_AS_CHAR == nAnchorTyp) || 527 (FLY_AT_CHAR == nAnchorTyp)) 528 { 529 if ( nCntnt > static_cast<SwTxtNode*>(pNd)->GetTxt().Len() ) 530 { 531 pNd = 0; // invalid position 532 } 533 else 534 { 535 aPos.nContent.Assign(static_cast<SwTxtNode*>(pNd), nCntnt); 536 } 537 } 538 if ( pNd ) 539 { 540 rAnchor.SetAnchor( &aPos ); 541 } 542 } 543 544 if( !pNd ) 545 { 546 // ungueltige Position - setze auf 1. Seite 547 rAnchor.SetType( FLY_AT_PAGE ); 548 rAnchor.SetPageNum( 1 ); 549 } 550 } 551 else 552 rAnchor.SetPageNum( nCntnt ); 553 } 554 555 void SwUndoSetFlyFmt::UndoImpl(::sw::UndoRedoContext & rContext) 556 { 557 SwDoc & rDoc = rContext.GetDoc(); 558 559 // ist das neue Format noch vorhanden ?? 560 if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmtPtr)pOldFmt ) ) 561 { 562 if( bAnchorChgd ) 563 pFrmFmt->DelFrms(); 564 565 if( pFrmFmt->DerivedFrom() != pOldFmt ) 566 pFrmFmt->SetDerivedFrom( pOldFmt ); 567 568 SfxItemIter aIter( *pItemSet ); 569 const SfxPoolItem* pItem = aIter.GetCurItem(); 570 while( pItem ) 571 { 572 if( IsInvalidItem( pItem )) 573 pFrmFmt->ResetFmtAttr( pItemSet->GetWhichByPos( 574 aIter.GetCurPos() )); 575 else 576 pFrmFmt->SetFmtAttr( *pItem ); 577 578 if( aIter.IsAtEnd() ) 579 break; 580 pItem = aIter.NextItem(); 581 } 582 583 if( bAnchorChgd ) 584 { 585 const SwFmtAnchor& rOldAnch = pFrmFmt->GetAnchor(); 586 if (FLY_AS_CHAR == rOldAnch.GetAnchorId()) 587 { 588 // Bei InCntnt's wird es spannend: Das TxtAttribut muss 589 // vernichtet werden. Leider reisst dies neben den Frms 590 // auch noch das Format mit in sein Grab. Um dass zu 591 // unterbinden loesen wir vorher die Verbindung zwischen 592 // Attribut und Format. 593 const SwPosition *pPos = rOldAnch.GetCntntAnchor(); 594 SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode(); 595 ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." ); 596 const xub_StrLen nIdx = pPos->nContent.GetIndex(); 597 SwTxtAttr * pHnt = pTxtNode->GetTxtAttrForCharAt( 598 nIdx, RES_TXTATR_FLYCNT ); 599 ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT, 600 "Missing FlyInCnt-Hint." ); 601 ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pFrmFmt, 602 "Wrong TxtFlyCnt-Hint." ); 603 const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt(); 604 605 // Die Verbindung ist geloest, jetzt muss noch das Attribut 606 // vernichtet werden. 607 pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx ); 608 } 609 610 // Anker umsetzen 611 SwFmtAnchor aNewAnchor( (RndStdIds) nOldAnchorTyp ); 612 GetAnchor( aNewAnchor, nOldNode, nOldCntnt ); 613 pFrmFmt->SetFmtAttr( aNewAnchor ); 614 615 if (FLY_AS_CHAR == aNewAnchor.GetAnchorId()) 616 { 617 SwPosition* pPos = (SwPosition*)aNewAnchor.GetCntntAnchor(); 618 SwFmtFlyCnt aFmt( pFrmFmt ); 619 pPos->nNode.GetNode().GetTxtNode()->InsertItem( aFmt, 620 nOldCntnt, 0 ); 621 } 622 623 pFrmFmt->MakeFrms(); 624 } 625 rContext.SetSelections(pFrmFmt, 0); 626 } 627 } 628 629 void SwUndoSetFlyFmt::RedoImpl(::sw::UndoRedoContext & rContext) 630 { 631 SwDoc & rDoc = rContext.GetDoc(); 632 633 // ist das neue Format noch vorhanden ?? 634 if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (const SwFrmFmtPtr)pNewFmt ) ) 635 { 636 637 if( bAnchorChgd ) 638 { 639 SwFmtAnchor aNewAnchor( (RndStdIds) nNewAnchorTyp ); 640 GetAnchor( aNewAnchor, nNewNode, nNewCntnt ); 641 SfxItemSet aSet( rDoc.GetAttrPool(), aFrmFmtSetRange ); 642 aSet.Put( aNewAnchor ); 643 rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, &aSet ); 644 } 645 else 646 rDoc.SetFrmFmtToFly( *pFrmFmt, *pNewFmt, 0 ); 647 648 rContext.SetSelections(pFrmFmt, 0); 649 } 650 } 651 652 void SwUndoSetFlyFmt::PutAttr( sal_uInt16 nWhich, const SfxPoolItem* pItem ) 653 { 654 if( pItem && pItem != GetDfltAttr( nWhich ) ) 655 { 656 // Sonderbehandlung fuer den Anchor 657 if( RES_ANCHOR == nWhich ) 658 { 659 // nur den 1. Ankerwechsel vermerken 660 ASSERT( !bAnchorChgd, "mehrfacher Ankerwechsel nicht erlaubt!" ); 661 662 bAnchorChgd = sal_True; 663 664 const SwFmtAnchor* pAnchor = (SwFmtAnchor*)pItem; 665 switch( nOldAnchorTyp = static_cast<sal_uInt16>(pAnchor->GetAnchorId()) ) 666 { 667 case FLY_AS_CHAR: 668 case FLY_AT_CHAR: 669 nOldCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex(); 670 case FLY_AT_PARA: 671 case FLY_AT_FLY: 672 nOldNode = pAnchor->GetCntntAnchor()->nNode.GetIndex(); 673 break; 674 675 default: 676 nOldCntnt = pAnchor->GetPageNum(); 677 } 678 679 pAnchor = (SwFmtAnchor*)&pFrmFmt->GetAnchor(); 680 switch( nNewAnchorTyp = static_cast<sal_uInt16>(pAnchor->GetAnchorId()) ) 681 { 682 case FLY_AS_CHAR: 683 case FLY_AT_CHAR: 684 nNewCntnt = pAnchor->GetCntntAnchor()->nContent.GetIndex(); 685 case FLY_AT_PARA: 686 case FLY_AT_FLY: 687 nNewNode = pAnchor->GetCntntAnchor()->nNode.GetIndex(); 688 break; 689 690 default: 691 nNewCntnt = pAnchor->GetPageNum(); 692 } 693 } 694 else 695 pItemSet->Put( *pItem ); 696 } 697 else 698 pItemSet->InvalidateItem( nWhich ); 699 } 700 701 void SwUndoSetFlyFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* ) 702 { 703 if( pOld ) 704 { 705 sal_uInt16 nWhich = pOld->Which(); 706 707 if( nWhich < POOLATTR_END ) 708 PutAttr( nWhich, pOld ); 709 else if( RES_ATTRSET_CHG == nWhich ) 710 { 711 SfxItemIter aIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); 712 const SfxPoolItem* pItem = aIter.GetCurItem(); 713 while( pItem ) 714 { 715 PutAttr( pItem->Which(), pItem ); 716 if( aIter.IsAtEnd() ) 717 break; 718 pItem = aIter.NextItem(); 719 } 720 } 721 } 722 } 723 724