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 28 #include <hintids.hxx> 29 30 #include <vcl/graph.hxx> 31 #include <sot/formats.hxx> 32 #include <sot/storage.hxx> 33 #include <unotools/pathoptions.hxx> 34 #include <sfx2/dispatch.hxx> 35 #include <sfx2/viewsh.hxx> 36 #include <svx/xexch.hxx> 37 #include <svx/xflasit.hxx> 38 #include <svx/xfillit0.hxx> 39 #include <svx/xflclit.hxx> 40 #include <editeng/brshitem.hxx> 41 #include <svx/svdocapt.hxx> 42 #include <svx/svdouno.hxx> 43 #include <svx/xfillit.hxx> 44 #include <svx/svdpage.hxx> 45 #include <svx/svdogrp.hxx> 46 #include <svx/xoutbmp.hxx> 47 #include <svx/svdoole2.hxx> 48 #include <svx/fmmodel.hxx> 49 #include <svx/unomodel.hxx> 50 // --> OD 2005-08-03 #i50824# 51 #include <svx/svditer.hxx> 52 // <-- 53 // --> OD 2006-03-01 #b6382898# 54 #include <svx/svdograf.hxx> 55 // <-- 56 #include <unotools/streamwrap.hxx> 57 #include <fmtanchr.hxx> 58 #include <fmtcntnt.hxx> 59 #include <fmtornt.hxx> 60 #include <fmtflcnt.hxx> 61 #include <frmfmt.hxx> 62 #include <docary.hxx> 63 #include <txtfrm.hxx> 64 #include <txtflcnt.hxx> 65 #include <fesh.hxx> 66 #include <doc.hxx> 67 #include <IDocumentUndoRedo.hxx> 68 #include <rootfrm.hxx> 69 #include <ndtxt.hxx> 70 #include <pam.hxx> 71 #include <tblsel.hxx> 72 #include <swtable.hxx> 73 #include <flyfrm.hxx> 74 #include <pagefrm.hxx> 75 #include <fldbas.hxx> 76 #include <edimp.hxx> 77 #include <swundo.hxx> 78 #include <viewimp.hxx> 79 #include <dview.hxx> 80 #include <dcontact.hxx> 81 #include <dflyobj.hxx> 82 #include <docsh.hxx> 83 #include <pagedesc.hxx> 84 #include <mvsave.hxx> 85 #include <vcl/virdev.hxx> 86 87 88 using namespace ::com::sun::star; 89 90 /************************************************************************* 91 |* 92 |* SwFEShell::Copy() Copy fuer das Interne Clipboard. 93 |* Kopiert alle Selektionen in das Clipboard. 94 |* 95 |* Ersterstellung JP ?? 96 |* Letzte Aenderung MA 22. Feb. 95 97 | 98 |*************************************************************************/ 99 100 sal_Bool SwFEShell::Copy( SwDoc* pClpDoc, const String* pNewClpTxt ) 101 { 102 ASSERT( pClpDoc, "kein Clipboard-Dokument" ); 103 104 pClpDoc->GetIDocumentUndoRedo().DoUndo(false); // always false! 105 106 // steht noch Inhalt im ClpDocument, dann muss dieser geloescht werden 107 SwNodeIndex aSttIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 ); 108 SwTxtNode* pTxtNd = aSttIdx.GetNode().GetTxtNode(); 109 if( !pTxtNd || pTxtNd->GetTxt().Len() || 110 aSttIdx.GetIndex()+1 != pClpDoc->GetNodes().GetEndOfContent().GetIndex() ) 111 { 112 pClpDoc->GetNodes().Delete( aSttIdx, 113 pClpDoc->GetNodes().GetEndOfContent().GetIndex() - aSttIdx.GetIndex() ); 114 pTxtNd = pClpDoc->GetNodes().MakeTxtNode( aSttIdx, 115 (SwTxtFmtColl*)pClpDoc->GetDfltTxtFmtColl() ); 116 aSttIdx--; 117 } 118 119 // stehen noch FlyFrames rum, loesche auch diese 120 for( sal_uInt16 n = 0; n < pClpDoc->GetSpzFrmFmts()->Count(); ++n ) 121 { 122 SwFlyFrmFmt* pFly = (SwFlyFrmFmt*)(*pClpDoc->GetSpzFrmFmts())[n]; 123 pClpDoc->DelLayoutFmt( pFly ); 124 } 125 pClpDoc->GCFieldTypes(); // loesche die FieldTypes 126 127 // wurde ein String uebergeben, so kopiere diesen in das Clipboard- 128 // Dokument. Somit kann auch der Calculator das interne Clipboard 129 // benutzen. 130 if( pNewClpTxt ) 131 { 132 pTxtNd->InsertText( *pNewClpTxt, SwIndex( pTxtNd ) ); 133 return sal_True; // das wars. 134 } 135 136 pClpDoc->LockExpFlds(); 137 pClpDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES ); 138 sal_Bool bRet; 139 140 // soll ein FlyFrame kopiert werden ? 141 if( IsFrmSelected() ) 142 { 143 // hole das FlyFormat 144 SwFlyFrm* pFly = FindFlyFrm(); 145 SwFrmFmt* pFlyFmt = pFly->GetFmt(); 146 SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() ); 147 148 if ((FLY_AT_PARA == aAnchor.GetAnchorId()) || 149 (FLY_AT_CHAR == aAnchor.GetAnchorId()) || 150 (FLY_AT_FLY == aAnchor.GetAnchorId()) || 151 (FLY_AS_CHAR == aAnchor.GetAnchorId())) 152 { 153 SwPosition aPos( aSttIdx ); 154 if ( FLY_AS_CHAR == aAnchor.GetAnchorId() ) 155 { 156 aPos.nContent.Assign( pTxtNd, 0 ); 157 } 158 aAnchor.SetAnchor( &aPos ); 159 } 160 pFlyFmt = pClpDoc->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true ); 161 162 // sorge dafuer das das "RootFmt" als erstes im SpzArray-steht 163 // (Es wurden ggf. Flys in Flys kopiert. 164 SwSpzFrmFmts& rSpzFrmFmts = *(SwSpzFrmFmts*)pClpDoc->GetSpzFrmFmts(); 165 if( rSpzFrmFmts[ 0 ] != pFlyFmt ) 166 { 167 sal_uInt16 nPos = rSpzFrmFmts.GetPos( pFlyFmt ); 168 ASSERT( nPos != USHRT_MAX, "Fly steht nicht im Spz-Array" ); 169 170 rSpzFrmFmts.Remove( nPos ); 171 rSpzFrmFmts.Insert( pFlyFmt, 0 ); 172 } 173 174 if ( FLY_AS_CHAR == aAnchor.GetAnchorId() ) 175 { 176 // JP 13.02.99 Bug 61863: wenn eine Rahmenselektion ins Clipboard 177 // gestellt wird, so muss beim Pasten auch wieder 178 // eine solche vorgefunden werden. Also muss im Node 179 // das kopierte TextAttribut wieder entfernt werden, 180 // sonst wird es als TextSelektion erkannt 181 const SwIndex& rIdx = pFlyFmt->GetAnchor().GetCntntAnchor()->nContent; 182 SwTxtFlyCnt *const pTxtFly = static_cast<SwTxtFlyCnt *>( 183 pTxtNd->GetTxtAttrForCharAt( 184 rIdx.GetIndex(), RES_TXTATR_FLYCNT)); 185 if( pTxtFly ) 186 { 187 ((SwFmtFlyCnt&)pTxtFly->GetFlyCnt()).SetFlyFmt( 0 ); 188 pTxtNd->EraseText( rIdx, 1 ); 189 } 190 } 191 bRet = sal_True; 192 } 193 else if ( IsObjSelected() ) 194 { 195 SwPosition aPos( aSttIdx, SwIndex( pTxtNd, 0 )); 196 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 197 for ( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 198 { 199 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 200 201 if( Imp()->GetDrawView()->IsGroupEntered() || 202 ( !pObj->GetUserCall() && pObj->GetUpGroup()) ) 203 { 204 SfxItemSet aSet( pClpDoc->GetAttrPool(), aFrmFmtSetRange ); 205 206 SwFmtAnchor aAnchor( FLY_AT_PARA ); 207 aAnchor.SetAnchor( &aPos ); 208 aSet.Put( aAnchor ); 209 210 SdrObject *const pNew = 211 pClpDoc->CloneSdrObj( *pObj, sal_False, sal_True ); 212 213 SwPaM aTemp(aPos); 214 pClpDoc->Insert(aTemp, *pNew, &aSet, NULL); 215 } 216 else 217 { 218 SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj ); 219 SwFrmFmt *pFmt = pContact->GetFmt(); 220 SwFmtAnchor aAnchor( pFmt->GetAnchor() ); 221 if ((FLY_AT_PARA == aAnchor.GetAnchorId()) || 222 (FLY_AT_CHAR == aAnchor.GetAnchorId()) || 223 (FLY_AT_FLY == aAnchor.GetAnchorId()) || 224 (FLY_AS_CHAR == aAnchor.GetAnchorId())) 225 { 226 aAnchor.SetAnchor( &aPos ); 227 } 228 229 pClpDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true ); 230 } 231 } 232 bRet = sal_True; 233 } 234 else 235 bRet = _CopySelToDoc( pClpDoc, 0 ); // kopiere die Selectionen 236 237 pClpDoc->SetRedlineMode_intern((RedlineMode_t)0 ); 238 pClpDoc->UnlockExpFlds(); 239 if( !pClpDoc->IsExpFldsLocked() ) 240 pClpDoc->UpdateExpFlds(NULL, true); 241 242 return bRet; 243 } 244 245 const Point &lcl_FindBasePos( const SwFrm *pFrm, const Point &rPt ) 246 { 247 const SwFrm *pF = pFrm; 248 while ( pF && !pF->Frm().IsInside( rPt ) ) 249 { 250 if ( pF->IsCntntFrm() ) 251 pF = ((SwCntntFrm*)pF)->GetFollow(); 252 else 253 pF = 0; 254 } 255 if ( pF ) 256 return pF->Frm().Pos(); 257 else 258 return pFrm->Frm().Pos(); 259 } 260 261 sal_Bool lcl_SetAnchor( const SwPosition& rPos, const SwNode& rNd, SwFlyFrm* pFly, 262 const Point& rInsPt, SwFEShell& rDestShell, SwFmtAnchor& rAnchor, 263 Point& rNewPos, sal_Bool bCheckFlyRecur ) 264 { 265 sal_Bool bRet = sal_True; 266 rAnchor.SetAnchor( &rPos ); 267 SwCntntFrm* pTmpFrm = rNd.GetCntntNode()->getLayoutFrm( rDestShell.GetLayout(), &rInsPt, 0, sal_False ); 268 SwFlyFrm *pTmpFly = pTmpFrm->FindFlyFrm(); 269 if( pTmpFly && bCheckFlyRecur && pFly->IsUpperOf( *pTmpFly ) ) 270 { 271 bRet = sal_False; 272 } 273 else if ( FLY_AT_FLY == rAnchor.GetAnchorId() ) 274 { 275 if( pTmpFly ) 276 { 277 const SwNodeIndex& rIdx = *pTmpFly->GetFmt()->GetCntnt().GetCntntIdx(); 278 SwPosition aPos( rIdx ); 279 rAnchor.SetAnchor( &aPos ); 280 rNewPos = pTmpFly->Frm().Pos(); 281 } 282 else 283 { 284 rAnchor.SetType( FLY_AT_PAGE ); 285 rAnchor.SetPageNum( rDestShell.GetPageNumber( rInsPt ) ); 286 const SwFrm *pPg = pTmpFrm->FindPageFrm(); 287 rNewPos = pPg->Frm().Pos(); 288 } 289 } 290 else 291 rNewPos = ::lcl_FindBasePos( pTmpFrm, rInsPt ); 292 return bRet; 293 } 294 295 sal_Bool SwFEShell::CopyDrawSel( SwFEShell* pDestShell, const Point& rSttPt, 296 const Point& rInsPt, sal_Bool bIsMove, sal_Bool bSelectInsert ) 297 { 298 sal_Bool bRet = sal_True; 299 300 //Die Liste muss kopiert werden, weil unten die neuen Objekte 301 //selektiert werden. 302 const SdrMarkList aMrkList( Imp()->GetDrawView()->GetMarkedObjectList() ); 303 sal_uLong nMarkCount = aMrkList.GetMarkCount(); 304 if( !pDestShell->Imp()->GetDrawView() ) 305 // sollte mal eine erzeugt werden 306 pDestShell->MakeDrawView(); 307 else if( bSelectInsert ) 308 pDestShell->Imp()->GetDrawView()->UnmarkAll(); 309 310 SdrPageView *pDestPgView = pDestShell->Imp()->GetPageView(), 311 *pSrcPgView = Imp()->GetPageView(); 312 SwDrawView *pDestDrwView = pDestShell->Imp()->GetDrawView(), 313 *pSrcDrwView = Imp()->GetDrawView(); 314 SwDoc* pDestDoc = pDestShell->GetDoc(); 315 316 Size aSiz( rInsPt.X() - rSttPt.X(), rInsPt.Y() - rSttPt.Y() ); 317 for( sal_uInt16 i = 0; i < nMarkCount; ++i ) 318 { 319 SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj(); 320 321 SwDrawContact *pContact = (SwDrawContact*)GetUserCall( pObj ); 322 SwFrmFmt *pFmt = pContact->GetFmt(); 323 const SwFmtAnchor& rAnchor = pFmt->GetAnchor(); 324 325 sal_Bool bInsWithFmt = sal_True; 326 327 if( pDestDrwView->IsGroupEntered() ) 328 { 329 // in die Gruppe einfuegen, wenns aus einer betretenen Gruppe 330 // kommt oder das Object nicht zeichengebunden ist 331 if( pSrcDrwView->IsGroupEntered() || 332 (FLY_AS_CHAR != rAnchor.GetAnchorId()) ) 333 334 { 335 SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove && 336 GetDoc() == pDestDoc, sal_False ); 337 pNew->NbcMove( aSiz ); 338 pDestDrwView->InsertObjectAtView( pNew, *pDestPgView ); 339 bInsWithFmt = sal_False; 340 } 341 } 342 343 if( bInsWithFmt ) 344 { 345 SwFmtAnchor aAnchor( rAnchor ); 346 Point aNewAnch; 347 348 if ((FLY_AT_PARA == aAnchor.GetAnchorId()) || 349 (FLY_AT_CHAR == aAnchor.GetAnchorId()) || 350 (FLY_AT_FLY == aAnchor.GetAnchorId()) || 351 (FLY_AS_CHAR == aAnchor.GetAnchorId())) 352 { 353 if ( this == pDestShell ) 354 { 355 //gleiche Shell? Dann erfrage die Position an der 356 //uebergebenen DokumentPosition 357 SwPosition aPos( *GetCrsr()->GetPoint() ); 358 Point aPt( rInsPt ); 359 aPt -= rSttPt - pObj->GetSnapRect().TopLeft(); 360 SwCrsrMoveState aState( MV_SETONLYTEXT ); 361 GetLayout()->GetCrsrOfst( &aPos, aPt, &aState ); 362 const SwNode *pNd; 363 if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() ) 364 bRet = sal_False; 365 else 366 bRet = ::lcl_SetAnchor( aPos, *pNd, 0, rInsPt, 367 *pDestShell, aAnchor, aNewAnch, sal_False ); 368 } 369 else 370 { 371 SwPaM *pCrsr = pDestShell->GetCrsr(); 372 if( pCrsr->GetNode()->IsNoTxtNode() ) 373 bRet = sal_False; 374 else 375 bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), 376 *pCrsr->GetNode(), 0, rInsPt, 377 *pDestShell, aAnchor, 378 aNewAnch, sal_False ); 379 } 380 } 381 else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() ) 382 { 383 aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) ); 384 const SwRootFrm* pTmpRoot = pDestShell->GetLayout(); 385 const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true ); 386 if ( pPg ) 387 aNewAnch = pPg->Frm().Pos(); 388 } 389 390 if( bRet ) 391 { 392 if( pSrcDrwView->IsGroupEntered() || 393 ( !pObj->GetUserCall() && pObj->GetUpGroup()) ) 394 { 395 SfxItemSet aSet( pDestDoc->GetAttrPool(),aFrmFmtSetRange); 396 aSet.Put( aAnchor ); 397 SdrObject* pNew = pDestDoc->CloneSdrObj( *pObj, bIsMove && 398 GetDoc() == pDestDoc, sal_True ); 399 pFmt = pDestDoc->Insert( *pDestShell->GetCrsr(), 400 *pNew, &aSet, NULL ); 401 } 402 else 403 pFmt = pDestDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true ); 404 405 //Kann 0 sein, weil Draws in Kopf-/Fusszeilen nicht erlaubt sind. 406 if ( pFmt ) 407 { 408 SdrObject* pNew = pFmt->FindSdrObject(); 409 if ( FLY_AS_CHAR != aAnchor.GetAnchorId() ) 410 { 411 Point aPos( rInsPt ); 412 aPos -= aNewAnch; 413 aPos -= rSttPt - pObj->GetSnapRect().TopLeft(); 414 // OD 2004-04-05 #i26791# - change attributes instead of 415 // direct positioning 416 pFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ) ); 417 pFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME ) ); 418 // --> OD 2005-04-15 #i47455# - notify draw frame format 419 // that position attributes are already set. 420 if ( pFmt->ISA(SwDrawFrmFmt) ) 421 { 422 static_cast<SwDrawFrmFmt*>(pFmt)->PosAttrSet(); 423 } 424 // <-- 425 } 426 if( bSelectInsert ) 427 pDestDrwView->MarkObj( pNew, pDestPgView ); 428 } 429 } 430 } 431 } 432 433 if ( bIsMove && bRet ) 434 { 435 if( pDestShell == this ) 436 { 437 const SdrMarkList aList( pSrcDrwView->GetMarkedObjectList() ); 438 pSrcDrwView->UnmarkAll(); 439 440 sal_uLong nMrkCnt = aMrkList.GetMarkCount(); 441 sal_uInt16 i; 442 for ( i = 0; i < nMrkCnt; ++i ) 443 { 444 SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj(); 445 pSrcDrwView->MarkObj( pObj, pSrcPgView ); 446 } 447 DelSelectedObj(); 448 nMrkCnt = aList.GetMarkCount(); 449 for ( i = 0; i < nMrkCnt; ++i ) 450 { 451 SdrObject *pObj = aList.GetMark( i )->GetMarkedSdrObj(); 452 pSrcDrwView->MarkObj( pObj, pSrcPgView ); 453 } 454 } 455 else 456 DelSelectedObj(); 457 } 458 459 return bRet; 460 } 461 462 sal_Bool SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt, 463 const Point& rInsPt, sal_Bool bIsMove, sal_Bool bSelectInsert ) 464 { 465 sal_Bool bRet = sal_False; 466 467 ASSERT( pDestShell, "Copy ohne DestShell." ); 468 ASSERT( this == pDestShell || !pDestShell->IsObjSelected(), 469 "Dest-Shell darf nie im Obj-Modus sein" ); 470 471 SET_CURR_SHELL( pDestShell ); 472 473 pDestShell->StartAllAction(); 474 pDestShell->GetDoc()->LockExpFlds(); 475 476 // Referenzen sollen verschoben werden. 477 sal_Bool bCopyIsMove = pDoc->IsCopyIsMove(); 478 if( bIsMove ) 479 // am Doc ein Flag setzen, damit in den TextNodes 480 pDoc->SetCopyIsMove( sal_True ); 481 482 RedlineMode_t eOldRedlMode = pDestShell->GetDoc()->GetRedlineMode(); 483 pDestShell->GetDoc()->SetRedlineMode_intern( (RedlineMode_t)(eOldRedlMode | nsRedlineMode_t::REDLINE_DELETE_REDLINES)); 484 485 // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle 486 // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen 487 // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen 488 // besorgt) 489 SwFieldType* pTblFldTyp = pDestShell->GetDoc()->GetSysFldType( RES_TABLEFLD ); 490 491 if( IsFrmSelected() ) 492 { 493 SwFlyFrm* pFly = FindFlyFrm(); 494 SwFrmFmt* pFlyFmt = pFly->GetFmt(); 495 SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() ); 496 bRet = sal_True; 497 Point aNewAnch; 498 499 if ((FLY_AT_PARA == aAnchor.GetAnchorId()) || 500 (FLY_AT_CHAR == aAnchor.GetAnchorId()) || 501 (FLY_AT_FLY == aAnchor.GetAnchorId()) || 502 (FLY_AS_CHAR == aAnchor.GetAnchorId())) 503 { 504 if ( this == pDestShell ) 505 { 506 // gleiche Shell? Dann erfrage die Position an der 507 // uebergebenen DokumentPosition 508 SwPosition aPos( *GetCrsr()->GetPoint() ); 509 Point aPt( rInsPt ); 510 aPt -= rSttPt - pFly->Frm().Pos(); 511 SwCrsrMoveState aState( MV_SETONLYTEXT ); 512 GetLayout()->GetCrsrOfst( &aPos, aPt, &aState ); 513 const SwNode *pNd; 514 if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() ) 515 bRet = sal_False; 516 else 517 { //Nicht in sich selbst kopieren 518 const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx(); 519 if ( aPos.nNode > *pTmp && aPos.nNode < 520 pTmp->GetNode().EndOfSectionIndex() ) 521 { 522 bRet = sal_False; 523 } 524 else 525 bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt, 526 *pDestShell, aAnchor, aNewAnch, sal_True ); 527 } 528 } 529 else 530 { 531 const SwPaM *pCrsr = pDestShell->GetCrsr(); 532 if( pCrsr->GetNode()->IsNoTxtNode() ) 533 bRet = sal_False; 534 else 535 bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), *pCrsr->GetNode(), 536 pFly, rInsPt, *pDestShell, aAnchor, 537 aNewAnch, GetDoc() == pDestShell->GetDoc()); 538 } 539 } 540 else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() ) 541 { 542 aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) ); 543 const SwRootFrm* pTmpRoot = pDestShell->GetLayout(); 544 const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true ); 545 if ( pPg ) 546 aNewAnch = pPg->Frm().Pos(); 547 } 548 else { 549 ASSERT( !this, "was fuer ein Anchor ist es denn?" ); 550 } 551 552 if( bRet ) 553 { 554 SwFrmFmt *pOldFmt = pFlyFmt; 555 pFlyFmt = pDestShell->GetDoc()->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true ); 556 557 if ( FLY_AS_CHAR != aAnchor.GetAnchorId() ) 558 { 559 Point aPos( rInsPt ); 560 aPos -= aNewAnch; 561 aPos -= rSttPt - pFly->Frm().Pos(); 562 pFlyFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(),text::HoriOrientation::NONE, text::RelOrientation::FRAME ) ); 563 pFlyFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(),text::VertOrientation::NONE, text::RelOrientation::FRAME ) ); 564 } 565 566 const Point aPt( pDestShell->GetCrsrDocPos() ); 567 568 if( bIsMove ) 569 GetDoc()->DelLayoutFmt( pOldFmt ); 570 571 // nur selektieren wenn es in der gleichen Shell verschoben/ 572 // kopiert wird 573 if( bSelectInsert ) 574 { 575 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aPt, sal_False ); 576 if( pFlyFrm ) 577 { 578 //JP 12.05.98: sollte das nicht im SelectFlyFrm stehen??? 579 pDestShell->Imp()->GetDrawView()->UnmarkAll(); 580 pDestShell->SelectFlyFrm( *pFlyFrm, sal_True ); 581 } 582 } 583 584 if( this != pDestShell && !pDestShell->HasShFcs() ) 585 pDestShell->Imp()->GetDrawView()->hideMarkHandles(); 586 } 587 } 588 else if ( IsObjSelected() ) 589 bRet = CopyDrawSel( pDestShell, rSttPt, rInsPt, bIsMove, bSelectInsert ); 590 else if( IsTableMode() ) 591 { 592 // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite 593 // von der Originalen an und kopiere die selectierten Boxen. 594 // Die Groessen werden prozentual korrigiert. 595 596 // lasse ueber das Layout die Boxen suchen 597 const SwTableNode* pTblNd; 598 SwSelBoxes aBoxes; 599 GetTblSel( *this, aBoxes ); 600 if( aBoxes.Count() && 601 0 != (pTblNd = aBoxes[0]->GetSttNd()->FindTableNode()) ) 602 { 603 SwPosition* pDstPos = 0; 604 if( this == pDestShell ) 605 { 606 // gleiche Shell? Dann erzeuge einen Crsr an der 607 // uebergebenen DokumentPosition 608 pDstPos = new SwPosition( *GetCrsr()->GetPoint() ); 609 Point aPt( rInsPt ); 610 GetLayout()->GetCrsrOfst( pDstPos, aPt ); 611 if( !pDstPos->nNode.GetNode().IsNoTxtNode() ) 612 bRet = sal_True; 613 } 614 else if( !pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() ) 615 { 616 pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() ); 617 bRet = sal_True; 618 } 619 620 if( bRet ) 621 { 622 if( GetDoc() == pDestShell->GetDoc() ) 623 ParkTblCrsr(); 624 625 bRet = pDestShell->GetDoc()->InsCopyOfTbl( *pDstPos, aBoxes,0, 626 bIsMove && this == pDestShell && 627 aBoxes.Count() == pTblNd->GetTable(). 628 GetTabSortBoxes().Count(), 629 this != pDestShell ); 630 631 if( this != pDestShell ) 632 *pDestShell->GetCrsr()->GetPoint() = *pDstPos; 633 634 // wieder alle geparkten Crsr erzeugen? 635 if( GetDoc() == pDestShell->GetDoc() ) 636 GetCrsr(); 637 638 // JP 16.04.99: Bug 64908 - InsPos setzen, damit der geparkte 639 // Cursor auf die EinfuegePos. positioniert wird 640 if( this == pDestShell ) 641 GetCrsrDocPos() = rInsPt; 642 } 643 delete pDstPos; 644 } 645 } 646 else 647 { 648 bRet = sal_True; 649 if( this == pDestShell ) 650 { 651 // gleiche Shell? Dann erfrage die Position an der 652 // uebergebenen DokumentPosition 653 SwPosition aPos( *GetCrsr()->GetPoint() ); 654 Point aPt( rInsPt ); 655 GetLayout()->GetCrsrOfst( &aPos, aPt ); 656 bRet = !aPos.nNode.GetNode().IsNoTxtNode(); 657 } 658 else if( pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() ) 659 bRet = sal_False; 660 661 if( bRet ) 662 bRet = 0 != SwEditShell::Copy( pDestShell ); 663 } 664 665 pDestShell->GetDoc()->SetRedlineMode_intern( eOldRedlMode ); 666 pDoc->SetCopyIsMove( bCopyIsMove ); 667 668 // wurden neue Tabellenformeln eingefuegt ? 669 if( pTblFldTyp->GetDepends() ) 670 { 671 // alte Actions beenden; die Tabellen-Frames werden angelegt und 672 // eine SSelection kann erzeugt werden 673 sal_uInt16 nActCnt; 674 for( nActCnt = 0; pDestShell->ActionPend(); ++nActCnt ) 675 pDestShell->EndAllAction(); 676 677 for( ; nActCnt; --nActCnt ) 678 pDestShell->StartAllAction(); 679 } 680 pDestShell->GetDoc()->UnlockExpFlds(); 681 pDestShell->GetDoc()->UpdateFlds(NULL, false); 682 683 pDestShell->EndAllAction(); 684 return bRet; 685 } 686 687 /************************************************************************* 688 |* 689 |* SwFEShell::Paste() Paste fuer das Interne Clipboard. 690 |* Kopiert den Inhalt vom Clipboard in das Dokument. 691 |* 692 |* Ersterstellung JP ?? 693 |* Letzte Aenderung MA 22. Feb. 95 694 | 695 |*************************************************************************/ 696 697 namespace { 698 typedef boost::shared_ptr<SwPaM> PaMPtr; 699 typedef boost::shared_ptr<SwPosition> PositionPtr; 700 typedef std::pair< PaMPtr, PositionPtr > Insertion; 701 } 702 703 sal_Bool SwFEShell::Paste( SwDoc* pClpDoc, sal_Bool bIncludingPageFrames ) 704 { 705 SET_CURR_SHELL( this ); 706 ASSERT( pClpDoc, "kein Clipboard-Dokument" ); 707 const sal_uInt16 nStartPageNumber = GetPhyPageNum(); 708 // dann bis zum Ende vom Nodes Array 709 SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 ); 710 SwPaM aCpyPam( aIdx ); //DocStart 711 712 // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle 713 // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen 714 // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen 715 // besorgt) 716 SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD ); 717 718 SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode()->GetTableNode(); 719 if( !pSrcNd ) // TabellenNode ? 720 { // nicht ueberspringen!! 721 SwCntntNode* pCNd = aCpyPam.GetNode()->GetCntntNode(); 722 if( pCNd ) 723 aCpyPam.GetPoint()->nContent.Assign( pCNd, 0 ); 724 else if( !aCpyPam.Move( fnMoveForward, fnGoNode )) 725 aCpyPam.Move( fnMoveBackward, fnGoNode ); 726 } 727 728 aCpyPam.SetMark(); 729 aCpyPam.Move( fnMoveForward, fnGoDoc ); 730 731 sal_Bool bRet = sal_True, bDelTbl = sal_True; 732 StartAllAction(); 733 GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL ); 734 GetDoc()->LockExpFlds(); 735 736 // When the clipboard content has been created by a rectangular selection 737 // the pasting is more sophisticated: 738 // every paragraph will be inserted into another position. 739 // The first positions are given by the actual cursor ring, 740 // if there are more text portions to insert than cursor in this ring, 741 // the additional insert positions will be created by moving the last 742 // cursor position into the next line (like pressing the cursor down key) 743 if( pClpDoc->IsColumnSelection() && !IsTableMode() ) 744 { 745 // Creation of the list of insert positions 746 std::list< Insertion > aCopyList; 747 // The number of text portions of the rectangular selection 748 const sal_uInt32 nSelCount = aCpyPam.GetPoint()->nNode.GetIndex() 749 - aCpyPam.GetMark()->nNode.GetIndex(); 750 sal_uInt32 nCount = nSelCount; 751 SwNodeIndex aClpIdx( aIdx ); 752 SwPaM* pStartCursor = GetCrsr(); 753 SwPaM* pCurrCrsr = pStartCursor; 754 sal_uInt32 nCursorCount = pStartCursor->numberOf(); 755 // If the target selection is a multi-selection, often the last and first 756 // cursor of the ring points to identical document positions. Then 757 // we should avoid double insertion of text portions... 758 while( nCursorCount > 1 && *pCurrCrsr->GetPoint() == 759 *(dynamic_cast<SwPaM*>(pCurrCrsr->GetPrev())->GetPoint()) ) 760 { 761 --nCursorCount; 762 pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext()); 763 pStartCursor = pCurrCrsr; 764 } 765 SwPosition aStartPos( *pStartCursor->GetPoint() ); 766 SwPosition aInsertPos( aStartPos ); // first insertion position 767 bool bCompletePara = false; 768 sal_uInt16 nMove = 0; 769 while( nCount ) 770 { 771 --nCount; 772 ASSERT( aIdx.GetNode().GetCntntNode(), "Who filled the clipboard?!" ) 773 if( aIdx.GetNode().GetCntntNode() ) // robust 774 { 775 Insertion aInsertion( PaMPtr( new SwPaM( aIdx ) ), 776 PositionPtr( new SwPosition( aInsertPos ) ) ); 777 ++aIdx; 778 aInsertion.first->SetMark(); 779 if( pStartCursor == pCurrCrsr->GetNext() ) 780 { // Now we have to look for insertion positions... 781 if( !nMove ) // Annotate the last given insert position 782 aStartPos = aInsertPos; 783 SwCursor aCrsr( aStartPos, 0, false); 784 // Check if we find another insert position by moving 785 // down the last given position 786 if( aCrsr.UpDown( sal_False, ++nMove, 0, 0 ) ) 787 aInsertPos = *aCrsr.GetPoint(); 788 else // if there is no paragraph we have to create it 789 bCompletePara = nCount > 0; 790 nCursorCount = 0; 791 } 792 else // as long as we find more insert positions in the cursor ring 793 { // we'll take them 794 pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext()); 795 aInsertPos = *pCurrCrsr->GetPoint(); 796 --nCursorCount; 797 } 798 // If there are no more paragraphs e.g. at the end of a document, 799 // we insert complete paragraphs instead of text portions 800 if( bCompletePara ) 801 aInsertion.first->GetPoint()->nNode = aIdx; 802 else 803 aInsertion.first->GetPoint()->nContent = 804 aInsertion.first->GetCntntNode()->Len(); 805 aCopyList.push_back( aInsertion ); 806 } 807 // If there are no text portions left but there are some more 808 // cursor positions to fill we have to restart with the first 809 // text portion 810 if( !nCount && nCursorCount ) 811 { 812 nCount = std::min( nSelCount, nCursorCount ); 813 aIdx = aClpIdx; // Start of clipboard content 814 } 815 } 816 std::list< Insertion >::const_iterator pCurr = aCopyList.begin(); 817 std::list< Insertion >::const_iterator pEnd = aCopyList.end(); 818 while( pCurr != pEnd ) 819 { 820 SwPosition& rInsPos = *pCurr->second; 821 SwPaM& rCopy = *pCurr->first; 822 const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().FindTableBoxStartNode(); 823 if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex() && 824 rCopy.GetPoint()->nNode != rCopy.GetMark()->nNode ) 825 { 826 // if more than one node will be copied into a cell 827 // the box attributes have to be removed 828 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode ); 829 } 830 { 831 SwNodeIndex aIndexBefore(rInsPos.nNode); 832 aIndexBefore--; 833 pClpDoc->CopyRange( rCopy, rInsPos, false ); 834 { 835 aIndexBefore++; 836 SwPaM aPaM(SwPosition(aIndexBefore), 837 SwPosition(rInsPos.nNode)); 838 aPaM.GetDoc()->MakeUniqueNumRules(aPaM); 839 } 840 } 841 SaveTblBoxCntnt( &rInsPos ); 842 ++pCurr; 843 } 844 } 845 else 846 { 847 FOREACHPAM_START(this) 848 849 if( pSrcNd && 850 0 != ( pDestNd = GetDoc()->IsIdxInTbl( PCURCRSR->GetPoint()->nNode ))) 851 { 852 SwPosition aDestPos( *PCURCRSR->GetPoint() ); 853 854 sal_Bool bParkTblCrsr = sal_False; 855 const SwStartNode* pSttNd = PCURCRSR->GetNode()->FindTableBoxStartNode(); 856 857 // TABLE IN TABLE: Tabelle in Tabelle kopieren 858 // lasse ueber das Layout die Boxen suchen 859 SwSelBoxes aBoxes; 860 if( IsTableMode() ) // Tabellen-Selecktion ?? 861 { 862 GetTblSel( *this, aBoxes ); 863 ParkTblCrsr(); 864 bParkTblCrsr = sal_True; 865 } 866 else if( !PCURCRSR->HasMark() && PCURCRSR->GetNext() == PCURCRSR && 867 ( !pSrcNd->GetTable().IsTblComplex() || 868 pDestNd->GetTable().IsNewModel() ) ) 869 { 870 // dann die Tabelle "relativ" kopieren 871 SwTableBox* pBox = pDestNd->GetTable().GetTblBox( 872 pSttNd->GetIndex() ); 873 ASSERT( pBox, "Box steht nicht in dieser Tabelle" ); 874 aBoxes.Insert( pBox ); 875 } 876 877 SwNodeIndex aNdIdx( *pDestNd->EndOfSectionNode()); 878 if( !bParkTblCrsr ) 879 { 880 // erstmal aus der gesamten Tabelle raus 881 // ????? was ist mit Tabelle alleine im Rahmen ??????? 882 SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx ); 883 SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 )); 884 // #i59539: Don't remove all redline 885 SwPaM const tmpPaM(*pDestNd, *pDestNd->EndOfSectionNode()); 886 ::PaMCorrAbs(tmpPaM, aPos); 887 } 888 889 bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(), 890 sal_False, sal_False ); 891 892 if( bParkTblCrsr ) 893 GetCrsr(); 894 else 895 { 896 // und wieder in die Box zurueck 897 aNdIdx = *pSttNd; 898 SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx ); 899 SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 )); 900 // #i59539: Don't remove all redline 901 SwNode & rNode(PCURCRSR->GetPoint()->nNode.GetNode()); 902 SwCntntNode *const pCntntNode( rNode.GetCntntNode() ); 903 SwPaM const tmpPam(rNode, 0, 904 rNode, (pCntntNode) ? pCntntNode->Len() : 0); 905 ::PaMCorrAbs(tmpPam, aPos); 906 } 907 908 break; // aus der "while"-Schleife heraus 909 } 910 else if( *aCpyPam.GetPoint() == *aCpyPam.GetMark() && 911 pClpDoc->GetSpzFrmFmts()->Count() ) 912 { 913 // so langsam sollte mal eine DrawView erzeugt werden 914 if( !Imp()->GetDrawView() ) 915 MakeDrawView(); 916 917 for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i ) 918 { 919 sal_Bool bInsWithFmt = sal_True; 920 const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i]; 921 922 if( Imp()->GetDrawView()->IsGroupEntered() && 923 RES_DRAWFRMFMT == rCpyFmt.Which() && 924 (FLY_AS_CHAR != rCpyFmt.GetAnchor().GetAnchorId()) ) 925 { 926 const SdrObject* pSdrObj = rCpyFmt.FindSdrObject(); 927 if( pSdrObj ) 928 { 929 SdrObject* pNew = GetDoc()->CloneSdrObj( *pSdrObj, 930 sal_False, sal_False ); 931 932 // Insert object sets any anchor position to 0. 933 // Therefore we calculate the absolute position here 934 // and after the insert the anchor of the object 935 // is set to the anchor of the group object. 936 Rectangle aSnapRect = pNew->GetSnapRect(); 937 if( pNew->GetAnchorPos().X() || pNew->GetAnchorPos().Y() ) 938 { 939 const Point aPoint( 0, 0 ); 940 // OD 2004-04-05 #i26791# - direct drawing object 941 // positioning for group members 942 pNew->NbcSetAnchorPos( aPoint ); 943 pNew->NbcSetSnapRect( aSnapRect ); 944 } 945 946 Imp()->GetDrawView()->InsertObjectAtView( pNew, *Imp()->GetPageView() ); 947 948 Point aGrpAnchor( 0, 0 ); 949 SdrObjList* pList = pNew->GetObjList(); 950 if ( pList ) 951 { 952 SdrObject* pOwner = pList->GetOwnerObj(); 953 if ( pOwner ) 954 { 955 SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pOwner); 956 aGrpAnchor = pThisGroup->GetAnchorPos(); 957 } 958 } 959 960 // OD 2004-04-05 #i26791# - direct drawing object 961 // positioning for group members 962 pNew->NbcSetAnchorPos( aGrpAnchor ); 963 pNew->SetSnapRect( aSnapRect ); 964 965 bInsWithFmt = sal_False; 966 } 967 } 968 969 if( bInsWithFmt ) 970 { 971 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() ); 972 if ((FLY_AT_PARA == aAnchor.GetAnchorId()) || 973 (FLY_AT_CHAR == aAnchor.GetAnchorId()) || 974 (FLY_AS_CHAR == aAnchor.GetAnchorId())) 975 { 976 SwPosition* pPos = PCURCRSR->GetPoint(); 977 // #108784# allow shapes (no controls) in header/footer 978 if( RES_DRAWFRMFMT == rCpyFmt.Which() && 979 GetDoc()->IsInHeaderFooter( pPos->nNode ) && 980 CheckControlLayer( rCpyFmt.FindSdrObject() ) ) 981 continue; 982 983 aAnchor.SetAnchor( pPos ); 984 } 985 else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() ) 986 { 987 aAnchor.SetPageNum( GetPhyPageNum() ); 988 } 989 else if( FLY_AT_FLY == aAnchor.GetAnchorId() ) 990 { 991 Point aPt; 992 lcl_SetAnchor( *PCURCRSR->GetPoint(), *PCURCRSR->GetNode(), 993 0, aPt, *this, aAnchor, aPt, sal_False ); 994 } 995 996 SwFrmFmt * pNew = GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true ); 997 998 if( pNew ) 999 { 1000 if( RES_FLYFRMFMT == pNew->Which() ) 1001 { 1002 const Point aPt( GetCrsrDocPos() ); 1003 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pNew)-> 1004 GetFrm( &aPt, sal_False ); 1005 if( pFlyFrm ) 1006 SelectFlyFrm( *pFlyFrm, sal_True ); 1007 // immer nur den ersten Fly-Frame nehmen; die anderen 1008 // wurden ueber Fly in Fly ins ClipBoard kopiert ! 1009 break; 1010 } 1011 else 1012 { 1013 ASSERT( RES_DRAWFRMFMT == pNew->Which(), "Neues Format."); 1014 // --> OD 2005-09-01 #i52780# - drawing object has 1015 // to be made visible on paste. 1016 { 1017 SwDrawContact* pContact = 1018 static_cast<SwDrawContact*>(pNew->FindContactObj()); 1019 pContact->MoveObjToVisibleLayer( pContact->GetMaster() ); 1020 } 1021 // <-- 1022 SdrObject *pObj = pNew->FindSdrObject(); 1023 SwDrawView *pDV = Imp()->GetDrawView(); 1024 pDV->MarkObj( pObj, pDV->GetSdrPageView() ); 1025 // --> OD 2005-04-15 #i47455# - notify draw frame format 1026 // that position attributes are already set. 1027 if ( pNew->ISA(SwDrawFrmFmt) ) 1028 { 1029 static_cast<SwDrawFrmFmt*>(pNew)->PosAttrSet(); 1030 } 1031 // <-- 1032 } 1033 } 1034 } 1035 } 1036 } 1037 else 1038 { 1039 if( bDelTbl && IsTableMode() ) 1040 { 1041 SwEditShell::Delete(); 1042 bDelTbl = sal_False; 1043 } 1044 1045 SwPosition& rInsPos = *PCURCRSR->GetPoint(); 1046 const SwStartNode* pBoxNd = rInsPos.nNode.GetNode(). 1047 FindTableBoxStartNode(); 1048 if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - 1049 pBoxNd->GetIndex() && 1050 aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode ) 1051 { 1052 // es wird mehr als 1 Node in die akt. Box kopiert. Dann 1053 // muessen die BoxAttribute aber entfernt werden. 1054 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode ); 1055 } 1056 //find out if the clipboard document starts with a table 1057 bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode(); 1058 SwPosition aInsertPosition( rInsPos ); 1059 1060 { 1061 SwNodeIndex aIndexBefore(rInsPos.nNode); 1062 1063 aIndexBefore--; 1064 1065 pClpDoc->CopyRange( aCpyPam, rInsPos, false ); 1066 1067 { 1068 aIndexBefore++; 1069 SwPaM aPaM(SwPosition(aIndexBefore), 1070 SwPosition(rInsPos.nNode)); 1071 1072 aPaM.GetDoc()->MakeUniqueNumRules(aPaM); 1073 } 1074 } 1075 1076 SaveTblBoxCntnt( &rInsPos ); 1077 if(bIncludingPageFrames && bStartWithTable) 1078 { 1079 //remove the paragraph in front of the table 1080 SwPaM aPara(aInsertPosition); 1081 GetDoc()->DelFullPara(aPara); 1082 } 1083 //additionally copy page bound frames 1084 if( bIncludingPageFrames && pClpDoc->GetSpzFrmFmts()->Count() ) 1085 { 1086 // create a draw view if necessary 1087 if( !Imp()->GetDrawView() ) 1088 MakeDrawView(); 1089 1090 for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i ) 1091 { 1092 sal_Bool bInsWithFmt = sal_True; 1093 const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i]; 1094 if( bInsWithFmt ) 1095 { 1096 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() ); 1097 if ( FLY_AT_PAGE == aAnchor.GetAnchorId() ) 1098 { 1099 aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 ); 1100 } 1101 else 1102 continue; 1103 GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true ); 1104 } 1105 } 1106 } 1107 } 1108 1109 FOREACHPAM_END() 1110 } 1111 1112 GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL ); 1113 1114 // wurden neue Tabellenformeln eingefuegt ? 1115 if( pTblFldTyp->GetDepends() ) 1116 { 1117 // alte Actions beenden; die Tabellen-Frames werden angelegt und 1118 // eine Selection kann erzeugt werden 1119 sal_uInt16 nActCnt; 1120 for( nActCnt = 0; ActionPend(); ++nActCnt ) 1121 EndAllAction(); 1122 1123 for( ; nActCnt; --nActCnt ) 1124 StartAllAction(); 1125 } 1126 GetDoc()->UnlockExpFlds(); 1127 GetDoc()->UpdateFlds(NULL, false); 1128 EndAllAction(); 1129 1130 return bRet; 1131 } 1132 1133 /*-- 14.06.2004 13:31:17--------------------------------------------------- 1134 1135 -----------------------------------------------------------------------*/ 1136 sal_Bool SwFEShell::PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage) 1137 { 1138 Push(); 1139 if(!GotoPage(nStartPage)) 1140 { 1141 Pop(sal_False); 1142 return sal_False; 1143 } 1144 MovePage( fnPageCurr, fnPageStart ); 1145 SwPaM aCpyPam( *GetCrsr()->GetPoint() ); 1146 String sStartingPageDesc = GetPageDesc( GetCurPageDesc()).GetName(); 1147 SwPageDesc* pDesc = rToFill.FindPageDescByName( sStartingPageDesc, sal_True ); 1148 if( pDesc ) 1149 rToFill.ChgCurPageDesc( *pDesc ); 1150 1151 if(!GotoPage(nEndPage)) 1152 { 1153 Pop(sal_False); 1154 return sal_False; 1155 } 1156 //if the page starts with a table a paragraph has to be inserted before 1157 SwNode* pTableNode = aCpyPam.GetNode()->FindTableNode(); 1158 if(pTableNode) 1159 { 1160 //insert a paragraph 1161 StartUndo(UNDO_INSERT); 1162 SwNodeIndex aTblIdx( *pTableNode, -1 ); 1163 SwPosition aBefore(aTblIdx); 1164 if(GetDoc()->AppendTxtNode( aBefore )) 1165 { 1166 SwPaM aTmp(aBefore); 1167 aCpyPam = aTmp; 1168 } 1169 EndUndo(UNDO_INSERT); 1170 } 1171 1172 MovePage( fnPageCurr, fnPageEnd ); 1173 aCpyPam.SetMark(); 1174 *aCpyPam.GetMark() = *GetCrsr()->GetPoint(); 1175 1176 SET_CURR_SHELL( this ); 1177 1178 StartAllAction(); 1179 GetDoc()->LockExpFlds(); 1180 SetSelection(aCpyPam); 1181 // copy the text of the selection 1182 SwEditShell::Copy(&rToFill); 1183 1184 if(pTableNode) 1185 { 1186 //remove the inserted paragraph 1187 Undo(); 1188 //remove the paragraph in the second doc, too 1189 SwNodeIndex aIdx( rToFill.GetDoc()->GetNodes().GetEndOfExtras(), 2 ); 1190 SwPaM aPara( aIdx ); //DocStart 1191 rToFill.GetDoc()->DelFullPara(aPara); 1192 } 1193 // now the page bound objects 1194 //additionally copy page bound frames 1195 if( GetDoc()->GetSpzFrmFmts()->Count() ) 1196 { 1197 // create a draw view if necessary 1198 if( !rToFill.Imp()->GetDrawView() ) 1199 rToFill.MakeDrawView(); 1200 1201 for ( sal_uInt16 i = 0; i < GetDoc()->GetSpzFrmFmts()->Count(); ++i ) 1202 { 1203 const SwFrmFmt& rCpyFmt = *(*GetDoc()->GetSpzFrmFmts())[i]; 1204 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() ); 1205 if ((FLY_AT_PAGE == aAnchor.GetAnchorId()) && 1206 aAnchor.GetPageNum() >= nStartPage && aAnchor.GetPageNum() <= nEndPage) 1207 { 1208 aAnchor.SetPageNum( aAnchor.GetPageNum() - nStartPage + 1); 1209 } 1210 else 1211 continue; 1212 rToFill.GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true ); 1213 } 1214 } 1215 GetDoc()->UnlockExpFlds(); 1216 GetDoc()->UpdateFlds(NULL, false); 1217 Pop(sal_False); 1218 EndAllAction(); 1219 1220 return sal_True; 1221 } 1222 1223 sal_Bool SwFEShell::GetDrawObjGraphic( sal_uLong nFmt, Graphic& rGrf ) const 1224 { 1225 ASSERT( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" ); 1226 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 1227 sal_Bool bConvert = sal_True; 1228 if( rMrkList.GetMarkCount() ) 1229 { 1230 if( rMrkList.GetMarkCount() == 1 && 1231 rMrkList.GetMark( 0 )->GetMarkedSdrObj()->ISA(SwVirtFlyDrawObj) ) 1232 { 1233 // Rahmen selektiert 1234 if( CNT_GRF == GetCntType() ) 1235 { 1236 // --> OD 2005-02-09 #119353# - robust 1237 const Graphic* pGrf( GetGraphic() ); 1238 if ( pGrf ) 1239 { 1240 Graphic aGrf( *pGrf ); 1241 if( SOT_FORMAT_GDIMETAFILE == nFmt ) 1242 { 1243 if( GRAPHIC_BITMAP != aGrf.GetType() ) 1244 { 1245 rGrf = aGrf; 1246 bConvert = sal_False; 1247 } 1248 else if( GetWin() ) 1249 { 1250 Size aSz; 1251 Point aPt; 1252 GetGrfSize( aSz ); 1253 1254 VirtualDevice aVirtDev; 1255 aVirtDev.EnableOutput( sal_False ); 1256 1257 MapMode aTmp( GetWin()->GetMapMode() ); 1258 aTmp.SetOrigin( aPt ); 1259 aVirtDev.SetMapMode( aTmp ); 1260 1261 GDIMetaFile aMtf; 1262 aMtf.Record( &aVirtDev ); 1263 aGrf.Draw( &aVirtDev, aPt, aSz ); 1264 aMtf.Stop(); 1265 aMtf.SetPrefMapMode( aTmp ); 1266 aMtf.SetPrefSize( aSz ); 1267 rGrf = aMtf; 1268 } 1269 } 1270 else if( GRAPHIC_BITMAP == aGrf.GetType() ) 1271 { 1272 rGrf = aGrf; 1273 bConvert = sal_False; 1274 } 1275 else 1276 { 1277 //fix(23806): Nicht die Originalgroesse, sondern die 1278 //aktuelle. Anderfalls kann es passieren, dass z.B. bei 1279 //Vektorgrafiken mal eben zig MB angefordert werden. 1280 const Size aSz( FindFlyFrm()->Prt().SSize() ); 1281 VirtualDevice aVirtDev( *GetWin() ); 1282 1283 MapMode aTmp( MAP_TWIP ); 1284 aVirtDev.SetMapMode( aTmp ); 1285 if( aVirtDev.SetOutputSize( aSz ) ) 1286 { 1287 aGrf.Draw( &aVirtDev, Point(), aSz ); 1288 rGrf = aVirtDev.GetBitmap( Point(), aSz ); 1289 } 1290 else 1291 { 1292 rGrf = aGrf; 1293 bConvert = sal_False; 1294 } 1295 } 1296 } 1297 // <-- 1298 } 1299 } 1300 else if( SOT_FORMAT_GDIMETAFILE == nFmt ) 1301 rGrf = Imp()->GetDrawView()->GetMarkedObjMetaFile(); 1302 else if( SOT_FORMAT_BITMAP == nFmt ) 1303 rGrf = Imp()->GetDrawView()->GetMarkedObjBitmapEx(); 1304 } 1305 return bConvert; 1306 } 1307 1308 // --> OD 2005-08-03 #i50824# 1309 // --> OD 2006-03-01 #b6382898# 1310 // replace method <lcl_RemoveOleObjsFromSdrModel> by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs> 1311 void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SdrModel* _pModel ) 1312 { 1313 for ( sal_uInt16 nPgNum = 0; nPgNum < _pModel->GetPageCount(); ++nPgNum ) 1314 { 1315 // setup object iterator in order to iterate through all objects 1316 // including objects in group objects, but exclusive group objects. 1317 SdrObjListIter aIter(*(_pModel->GetPage( nPgNum ))); 1318 while( aIter.IsMore() ) 1319 { 1320 SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() ); 1321 if( pOle2Obj ) 1322 { 1323 // found an ole2 shape 1324 SdrObjList* pObjList = pOle2Obj->GetObjList(); 1325 1326 // get its graphic 1327 Graphic aGraphic; 1328 pOle2Obj->Connect(); 1329 Graphic* pGraphic = pOle2Obj->GetGraphic(); 1330 if( pGraphic ) 1331 aGraphic = *pGraphic; 1332 pOle2Obj->Disconnect(); 1333 1334 // create new graphic shape with the ole graphic and shape size 1335 SdrGrafObj* pGraphicObj = new SdrGrafObj( aGraphic, pOle2Obj->GetCurrentBoundRect() ); 1336 // apply layer of ole2 shape at graphic shape 1337 pGraphicObj->SetLayer( pOle2Obj->GetLayer() ); 1338 1339 // replace ole2 shape with the new graphic object and delete the ol2 shape 1340 SdrObject* pRemovedObject = pObjList->ReplaceObject( pGraphicObj, pOle2Obj->GetOrdNum() ); 1341 SdrObject::Free( pRemovedObject ); 1342 } 1343 } 1344 } 1345 } 1346 // <-- 1347 void SwFEShell::Paste( SvStream& rStrm, sal_uInt16 nAction, const Point* pPt ) 1348 { 1349 SET_CURR_SHELL( this ); 1350 StartAllAction(); 1351 StartUndo(); 1352 1353 SvtPathOptions aPathOpt; 1354 FmFormModel* pModel = new FmFormModel( aPathOpt.GetPalettePath(), 1355 0, GetDoc()->GetDocShell() ); 1356 pModel->GetItemPool().FreezeIdRanges(); 1357 1358 rStrm.Seek(0); 1359 1360 uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rStrm ) ); 1361 SvxDrawingLayerImport( pModel, xInputStream ); 1362 1363 if ( !Imp()->HasDrawView() ) 1364 Imp()->MakeDrawView(); 1365 1366 Point aPos( pPt ? *pPt : GetCharRect().Pos() ); 1367 SdrView *pView = Imp()->GetDrawView(); 1368 1369 //Drop auf bestehendes Objekt: Objekt ersetzen oder neu Attributieren. 1370 if( pModel->GetPageCount() > 0 && 1371 1 == pModel->GetPage(0)->GetObjCount() && 1372 1 == pView->GetMarkedObjectList().GetMarkCount() ) 1373 { 1374 // OD 10.07.2003 #110742# - replace a marked 'virtual' drawing object 1375 // by its corresponding 'master' drawing object in the mark list. 1376 SwDrawView::ReplaceMarkedDrawVirtObjs( *pView ); 1377 1378 SdrObject* pClpObj = pModel->GetPage(0)->GetObj(0); 1379 SdrObject* pOldObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj(); 1380 1381 if( SW_PASTESDR_SETATTR == nAction && pOldObj->ISA(SwVirtFlyDrawObj) ) 1382 nAction = SW_PASTESDR_REPLACE; 1383 1384 switch( nAction ) 1385 { 1386 case SW_PASTESDR_REPLACE: 1387 { 1388 const SwFrmFmt* pFmt(0); 1389 const SwFrm* pAnchor(0); 1390 if( pOldObj->ISA(SwVirtFlyDrawObj) ) 1391 { 1392 pFmt = FindFrmFmt( pOldObj ); 1393 1394 Point aNullPt; 1395 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFmt)->GetFrm( &aNullPt ); 1396 pAnchor = pFlyFrm->GetAnchorFrm(); 1397 1398 if( pAnchor->FindFooterOrHeader() ) 1399 { 1400 // wenn TextRahmen in der Kopf/Fusszeile steht, dann 1401 // nicht ersetzen, sondern nur einfuegen 1402 nAction = SW_PASTESDR_INSERT; 1403 break; 1404 } 1405 } 1406 1407 SdrObject* pNewObj = pClpObj->Clone(); 1408 Rectangle aOldObjRect( pOldObj->GetCurrentBoundRect() ); 1409 Size aOldObjSize( aOldObjRect.GetSize() ); 1410 Rectangle aNewRect( pNewObj->GetCurrentBoundRect() ); 1411 Size aNewSize( aNewRect.GetSize() ); 1412 1413 Fraction aScaleWidth( aOldObjSize.Width(), aNewSize.Width() ); 1414 Fraction aScaleHeight( aOldObjSize.Height(), aNewSize.Height()); 1415 pNewObj->NbcResize( aNewRect.TopLeft(), aScaleWidth, aScaleHeight); 1416 1417 Point aVec = aOldObjRect.TopLeft() - aNewRect.TopLeft(); 1418 pNewObj->NbcMove(Size(aVec.X(), aVec.Y())); 1419 1420 if( pNewObj->ISA( SdrUnoObj ) ) 1421 pNewObj->SetLayer( GetDoc()->GetControlsId() ); 1422 else if( pOldObj->ISA( SdrUnoObj ) ) 1423 pNewObj->SetLayer( GetDoc()->GetHeavenId() ); 1424 else 1425 pNewObj->SetLayer( pOldObj->GetLayer() ); 1426 1427 if( pOldObj->ISA(SwVirtFlyDrawObj) ) 1428 { 1429 // Attribute sichern und dam SdrObject setzen 1430 SfxItemSet aFrmSet( pDoc->GetAttrPool(), 1431 RES_SURROUND, RES_ANCHOR ); 1432 aFrmSet.Set( pFmt->GetAttrSet() ); 1433 1434 Point aNullPt; 1435 if( pAnchor->IsTxtFrm() && ((SwTxtFrm*)pAnchor)->IsFollow() ) 1436 { 1437 const SwTxtFrm* pTmp = (SwTxtFrm*)pAnchor; 1438 do { 1439 pTmp = pTmp->FindMaster(); 1440 ASSERT( pTmp, "Where's my Master?" ); 1441 } while( pTmp->IsFollow() ); 1442 pAnchor = pTmp; 1443 } 1444 if( pOldObj->ISA( SdrCaptionObj )) 1445 aNullPt = ((SdrCaptionObj*)pOldObj)->GetTailPos(); 1446 else 1447 aNullPt = aOldObjRect.TopLeft(); 1448 1449 Point aNewAnchor = pAnchor->GetFrmAnchorPos( ::HasWrap( pOldObj ) ); 1450 // OD 2004-04-05 #i26791# - direct positioning of Writer 1451 // fly frame object for <SwDoc::Insert(..)> 1452 pNewObj->NbcSetRelativePos( aNullPt - aNewAnchor ); 1453 pNewObj->NbcSetAnchorPos( aNewAnchor ); 1454 1455 pOldObj->GetOrdNum(); 1456 1457 DelSelectedObj(); 1458 1459 pFmt = GetDoc()->Insert( *GetCrsr(), *pNewObj, &aFrmSet, NULL ); 1460 } 1461 else 1462 pView->ReplaceObjectAtView( pOldObj, *Imp()->GetPageView(), pNewObj, sal_True ); 1463 } 1464 break; 1465 1466 case SW_PASTESDR_SETATTR: 1467 { 1468 SfxItemSet aSet( GetAttrPool() ); 1469 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pClpObj); 1470 1471 if(pSdrGrafObj) 1472 { 1473 SdrObject* pTarget = 0; 1474 1475 if(0 != pView->GetMarkedObjectList().GetMarkCount()) 1476 { 1477 // try to get target (if it's at least one, take first) 1478 SdrMark* pMark = pView->GetMarkedObjectList().GetMark(0); 1479 1480 if(pMark) 1481 { 1482 pTarget = pMark->GetMarkedSdrObj(); 1483 } 1484 } 1485 1486 if(pTarget) 1487 { 1488 // copy ItemSet from target 1489 aSet.Set(pTarget->GetMergedItemSet()); 1490 } 1491 1492 // for SdrGrafObj, use the graphic as fill style argument 1493 const Graphic& rGraphic = pSdrGrafObj->GetGraphic(); 1494 1495 if(GRAPHIC_NONE != rGraphic.GetType() && GRAPHIC_DEFAULT != rGraphic.GetType()) 1496 { 1497 aSet.Put(XFillBitmapItem(String(), rGraphic)); 1498 aSet.Put(XFillStyleItem(XFILL_BITMAP)); 1499 } 1500 } 1501 else 1502 { 1503 aSet.Put(pClpObj->GetMergedItemSet()); 1504 } 1505 1506 pView->SetAttributes( aSet, sal_False ); 1507 } 1508 break; 1509 1510 default: 1511 nAction = SW_PASTESDR_INSERT; 1512 break; 1513 } 1514 } 1515 else 1516 nAction = SW_PASTESDR_INSERT; 1517 1518 if( SW_PASTESDR_INSERT == nAction ) 1519 { 1520 ::sw::DrawUndoGuard drawUndoGuard(GetDoc()->GetIDocumentUndoRedo()); 1521 1522 sal_Bool bDesignMode = pView->IsDesignMode(); 1523 if( !bDesignMode ) 1524 pView->SetDesignMode( sal_True ); 1525 1526 // --> OD 2005-08-03 #i50824# 1527 // --> OD 2006-03-01 #b6382898# 1528 // method <lcl_RemoveOleObjsFromSdrModel> replaced by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs> 1529 lcl_ConvertSdrOle2ObjsToSdrGrafObjs( pModel ); 1530 // <-- 1531 pView->Paste( *pModel, aPos ); 1532 1533 sal_uLong nCnt = pView->GetMarkedObjectList().GetMarkCount(); 1534 if( nCnt ) 1535 { 1536 const Point aNull( 0, 0 ); 1537 for( sal_uLong i=0; i < nCnt; ++i ) 1538 { 1539 SdrObject *pObj = pView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj(); 1540 pObj->ImpSetAnchorPos( aNull ); 1541 } 1542 1543 pView->SetCurrentObj( OBJ_GRUP, SdrInventor ); 1544 if ( nCnt > 1 ) 1545 pView->GroupMarked(); 1546 SdrObject *pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); 1547 if( pObj->ISA( SdrUnoObj ) ) 1548 { 1549 pObj->SetLayer( GetDoc()->GetControlsId() ); 1550 bDesignMode = sal_True; 1551 } 1552 else 1553 pObj->SetLayer( GetDoc()->GetHeavenId() ); 1554 const Rectangle &rSnap = pObj->GetSnapRect(); 1555 const Size aDiff( rSnap.GetWidth()/2, rSnap.GetHeight()/2 ); 1556 pView->MoveMarkedObj( aDiff ); 1557 ImpEndCreate(); 1558 if( !bDesignMode ) 1559 pView->SetDesignMode( sal_False ); 1560 } 1561 } 1562 EndUndo(); 1563 EndAllAction(); 1564 delete pModel; 1565 } 1566 1567 sal_Bool SwFEShell::Paste( const Graphic &rGrf ) 1568 { 1569 SET_CURR_SHELL( this ); 1570 SdrObject* pObj; 1571 SdrView *pView = Imp()->GetDrawView(); 1572 1573 sal_Bool bRet = 1 == pView->GetMarkedObjectList().GetMarkCount() && 1574 (pObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj())->IsClosedObj() && 1575 !pObj->ISA( SdrOle2Obj ); 1576 1577 if( bRet ) 1578 { 1579 SfxItemSet aSet(GetAttrPool(), XATTR_FILLSTYLE, XATTR_FILLBITMAP); 1580 1581 aSet.Put(XFillStyleItem(XFILL_BITMAP)); 1582 aSet.Put(XFillBitmapItem(aEmptyStr, rGrf)); 1583 pView->SetAttributes(aSet, false); 1584 } 1585 return bRet; 1586 } 1587