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 #include <svx/svdundo.hxx> 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->InsertDrawObj(aTemp, *pNew, aSet ); 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->InsertDrawObj( *pDestShell->GetCrsr(), *pNew, aSet ); 400 } 401 else 402 pFmt = pDestDoc->CopyLayoutFmt( *pFmt, aAnchor, true, true ); 403 404 //Kann 0 sein, weil Draws in Kopf-/Fusszeilen nicht erlaubt sind. 405 if ( pFmt ) 406 { 407 SdrObject* pNew = pFmt->FindSdrObject(); 408 if ( FLY_AS_CHAR != aAnchor.GetAnchorId() ) 409 { 410 Point aPos( rInsPt ); 411 aPos -= aNewAnch; 412 aPos -= rSttPt - pObj->GetSnapRect().TopLeft(); 413 // OD 2004-04-05 #i26791# - change attributes instead of 414 // direct positioning 415 pFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ) ); 416 pFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(), text::VertOrientation::NONE, text::RelOrientation::FRAME ) ); 417 // --> OD 2005-04-15 #i47455# - notify draw frame format 418 // that position attributes are already set. 419 if ( pFmt->ISA(SwDrawFrmFmt) ) 420 { 421 static_cast<SwDrawFrmFmt*>(pFmt)->PosAttrSet(); 422 } 423 // <-- 424 } 425 if( bSelectInsert ) 426 pDestDrwView->MarkObj( pNew, pDestPgView ); 427 } 428 } 429 } 430 } 431 432 if ( bIsMove && bRet ) 433 { 434 if( pDestShell == this ) 435 { 436 const SdrMarkList aList( pSrcDrwView->GetMarkedObjectList() ); 437 pSrcDrwView->UnmarkAll(); 438 439 sal_uLong nMrkCnt = aMrkList.GetMarkCount(); 440 sal_uInt16 i; 441 for ( i = 0; i < nMrkCnt; ++i ) 442 { 443 SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj(); 444 pSrcDrwView->MarkObj( pObj, pSrcPgView ); 445 } 446 DelSelectedObj(); 447 nMrkCnt = aList.GetMarkCount(); 448 for ( i = 0; i < nMrkCnt; ++i ) 449 { 450 SdrObject *pObj = aList.GetMark( i )->GetMarkedSdrObj(); 451 pSrcDrwView->MarkObj( pObj, pSrcPgView ); 452 } 453 } 454 else 455 DelSelectedObj(); 456 } 457 458 return bRet; 459 } 460 461 sal_Bool SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt, 462 const Point& rInsPt, sal_Bool bIsMove, sal_Bool bSelectInsert ) 463 { 464 sal_Bool bRet = sal_False; 465 466 ASSERT( pDestShell, "Copy ohne DestShell." ); 467 ASSERT( this == pDestShell || !pDestShell->IsObjSelected(), 468 "Dest-Shell darf nie im Obj-Modus sein" ); 469 470 SET_CURR_SHELL( pDestShell ); 471 472 pDestShell->StartAllAction(); 473 pDestShell->GetDoc()->LockExpFlds(); 474 475 // Referenzen sollen verschoben werden. 476 sal_Bool bCopyIsMove = pDoc->IsCopyIsMove(); 477 if( bIsMove ) 478 // am Doc ein Flag setzen, damit in den TextNodes 479 pDoc->SetCopyIsMove( sal_True ); 480 481 RedlineMode_t eOldRedlMode = pDestShell->GetDoc()->GetRedlineMode(); 482 pDestShell->GetDoc()->SetRedlineMode_intern( (RedlineMode_t)(eOldRedlMode | nsRedlineMode_t::REDLINE_DELETE_REDLINES)); 483 484 // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle 485 // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen 486 // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen 487 // besorgt) 488 SwFieldType* pTblFldTyp = pDestShell->GetDoc()->GetSysFldType( RES_TABLEFLD ); 489 490 if( IsFrmSelected() ) 491 { 492 SwFlyFrm* pFly = FindFlyFrm(); 493 SwFrmFmt* pFlyFmt = pFly->GetFmt(); 494 SwFmtAnchor aAnchor( pFlyFmt->GetAnchor() ); 495 bRet = sal_True; 496 Point aNewAnch; 497 498 if ((FLY_AT_PARA == aAnchor.GetAnchorId()) || 499 (FLY_AT_CHAR == aAnchor.GetAnchorId()) || 500 (FLY_AT_FLY == aAnchor.GetAnchorId()) || 501 (FLY_AS_CHAR == aAnchor.GetAnchorId())) 502 { 503 if ( this == pDestShell ) 504 { 505 // gleiche Shell? Dann erfrage die Position an der 506 // uebergebenen DokumentPosition 507 SwPosition aPos( *GetCrsr()->GetPoint() ); 508 Point aPt( rInsPt ); 509 aPt -= rSttPt - pFly->Frm().Pos(); 510 SwCrsrMoveState aState( MV_SETONLYTEXT ); 511 GetLayout()->GetCrsrOfst( &aPos, aPt, &aState ); 512 const SwNode *pNd; 513 if( (pNd = &aPos.nNode.GetNode())->IsNoTxtNode() ) 514 bRet = sal_False; 515 else 516 { //Nicht in sich selbst kopieren 517 const SwNodeIndex *pTmp = pFlyFmt->GetCntnt().GetCntntIdx(); 518 if ( aPos.nNode > *pTmp && aPos.nNode < 519 pTmp->GetNode().EndOfSectionIndex() ) 520 { 521 bRet = sal_False; 522 } 523 else 524 bRet = ::lcl_SetAnchor( aPos, *pNd, pFly, rInsPt, 525 *pDestShell, aAnchor, aNewAnch, sal_True ); 526 } 527 } 528 else 529 { 530 const SwPaM *pCrsr = pDestShell->GetCrsr(); 531 if( pCrsr->GetNode()->IsNoTxtNode() ) 532 bRet = sal_False; 533 else 534 bRet = ::lcl_SetAnchor( *pCrsr->GetPoint(), *pCrsr->GetNode(), 535 pFly, rInsPt, *pDestShell, aAnchor, 536 aNewAnch, GetDoc() == pDestShell->GetDoc()); 537 } 538 } 539 else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() ) 540 { 541 aAnchor.SetPageNum( pDestShell->GetPageNumber( rInsPt ) ); 542 const SwRootFrm* pTmpRoot = pDestShell->GetLayout(); 543 const SwFrm* pPg = pTmpRoot->GetPageAtPos( rInsPt, 0, true ); 544 if ( pPg ) 545 aNewAnch = pPg->Frm().Pos(); 546 } 547 else { 548 ASSERT( !this, "was fuer ein Anchor ist es denn?" ); 549 } 550 551 if( bRet ) 552 { 553 SwFrmFmt *pOldFmt = pFlyFmt; 554 pFlyFmt = pDestShell->GetDoc()->CopyLayoutFmt( *pFlyFmt, aAnchor, true, true ); 555 556 if ( FLY_AS_CHAR != aAnchor.GetAnchorId() ) 557 { 558 Point aPos( rInsPt ); 559 aPos -= aNewAnch; 560 aPos -= rSttPt - pFly->Frm().Pos(); 561 pFlyFmt->SetFmtAttr( SwFmtHoriOrient( aPos.X(),text::HoriOrientation::NONE, text::RelOrientation::FRAME ) ); 562 pFlyFmt->SetFmtAttr( SwFmtVertOrient( aPos.Y(),text::VertOrientation::NONE, text::RelOrientation::FRAME ) ); 563 } 564 565 const Point aPt( pDestShell->GetCrsrDocPos() ); 566 567 if( bIsMove ) 568 GetDoc()->DelLayoutFmt( pOldFmt ); 569 570 // nur selektieren wenn es in der gleichen Shell verschoben/ 571 // kopiert wird 572 if( bSelectInsert ) 573 { 574 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aPt, sal_False ); 575 if( pFlyFrm ) 576 { 577 //JP 12.05.98: sollte das nicht im SelectFlyFrm stehen??? 578 pDestShell->Imp()->GetDrawView()->UnmarkAll(); 579 pDestShell->SelectFlyFrm( *pFlyFrm, sal_True ); 580 } 581 } 582 583 if( this != pDestShell && !pDestShell->HasShFcs() ) 584 pDestShell->Imp()->GetDrawView()->hideMarkHandles(); 585 } 586 } 587 else if ( IsObjSelected() ) 588 bRet = CopyDrawSel( pDestShell, rSttPt, rInsPt, bIsMove, bSelectInsert ); 589 else if( IsTableMode() ) 590 { 591 // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite 592 // von der Originalen an und kopiere die selectierten Boxen. 593 // Die Groessen werden prozentual korrigiert. 594 595 // lasse ueber das Layout die Boxen suchen 596 const SwTableNode* pTblNd; 597 SwSelBoxes aBoxes; 598 GetTblSel( *this, aBoxes ); 599 if( aBoxes.Count() && 600 0 != (pTblNd = aBoxes[0]->GetSttNd()->FindTableNode()) ) 601 { 602 SwPosition* pDstPos = 0; 603 if( this == pDestShell ) 604 { 605 // gleiche Shell? Dann erzeuge einen Crsr an der 606 // uebergebenen DokumentPosition 607 pDstPos = new SwPosition( *GetCrsr()->GetPoint() ); 608 Point aPt( rInsPt ); 609 GetLayout()->GetCrsrOfst( pDstPos, aPt ); 610 if( !pDstPos->nNode.GetNode().IsNoTxtNode() ) 611 bRet = sal_True; 612 } 613 else if( !pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() ) 614 { 615 pDstPos = new SwPosition( *pDestShell->GetCrsr()->GetPoint() ); 616 bRet = sal_True; 617 } 618 619 if( bRet ) 620 { 621 if( GetDoc() == pDestShell->GetDoc() ) 622 ParkTblCrsr(); 623 624 bRet = pDestShell->GetDoc()->InsCopyOfTbl( *pDstPos, aBoxes,0, 625 bIsMove && this == pDestShell && 626 aBoxes.Count() == pTblNd->GetTable(). 627 GetTabSortBoxes().Count(), 628 this != pDestShell ); 629 630 if( this != pDestShell ) 631 *pDestShell->GetCrsr()->GetPoint() = *pDstPos; 632 633 // wieder alle geparkten Crsr erzeugen? 634 if( GetDoc() == pDestShell->GetDoc() ) 635 GetCrsr(); 636 637 // JP 16.04.99: Bug 64908 - InsPos setzen, damit der geparkte 638 // Cursor auf die EinfuegePos. positioniert wird 639 if( this == pDestShell ) 640 GetCrsrDocPos() = rInsPt; 641 } 642 delete pDstPos; 643 } 644 } 645 else 646 { 647 bRet = sal_True; 648 if( this == pDestShell ) 649 { 650 // gleiche Shell? Dann erfrage die Position an der 651 // uebergebenen DokumentPosition 652 SwPosition aPos( *GetCrsr()->GetPoint() ); 653 Point aPt( rInsPt ); 654 GetLayout()->GetCrsrOfst( &aPos, aPt ); 655 bRet = !aPos.nNode.GetNode().IsNoTxtNode(); 656 } 657 else if( pDestShell->GetCrsr()->GetNode()->IsNoTxtNode() ) 658 bRet = sal_False; 659 660 if( bRet ) 661 bRet = 0 != SwEditShell::Copy( pDestShell ); 662 } 663 664 pDestShell->GetDoc()->SetRedlineMode_intern( eOldRedlMode ); 665 pDoc->SetCopyIsMove( bCopyIsMove ); 666 667 // wurden neue Tabellenformeln eingefuegt ? 668 if( pTblFldTyp->GetDepends() ) 669 { 670 // alte Actions beenden; die Tabellen-Frames werden angelegt und 671 // eine SSelection kann erzeugt werden 672 sal_uInt16 nActCnt; 673 for( nActCnt = 0; pDestShell->ActionPend(); ++nActCnt ) 674 pDestShell->EndAllAction(); 675 676 for( ; nActCnt; --nActCnt ) 677 pDestShell->StartAllAction(); 678 } 679 pDestShell->GetDoc()->UnlockExpFlds(); 680 pDestShell->GetDoc()->UpdateFlds(NULL, false); 681 682 pDestShell->EndAllAction(); 683 return bRet; 684 } 685 686 /************************************************************************* 687 |* 688 |* SwFEShell::Paste() Paste fuer das Interne Clipboard. 689 |* Kopiert den Inhalt vom Clipboard in das Dokument. 690 |* 691 |* Ersterstellung JP ?? 692 |* Letzte Aenderung MA 22. Feb. 95 693 | 694 |*************************************************************************/ 695 696 namespace { 697 typedef boost::shared_ptr<SwPaM> PaMPtr; 698 typedef boost::shared_ptr<SwPosition> PositionPtr; 699 typedef std::pair< PaMPtr, PositionPtr > Insertion; 700 } 701 702 sal_Bool SwFEShell::Paste( SwDoc* pClpDoc, sal_Bool bIncludingPageFrames ) 703 { 704 SET_CURR_SHELL( this ); 705 ASSERT( pClpDoc, "kein Clipboard-Dokument" ); 706 const sal_uInt16 nStartPageNumber = GetPhyPageNum(); 707 // dann bis zum Ende vom Nodes Array 708 SwNodeIndex aIdx( pClpDoc->GetNodes().GetEndOfExtras(), 2 ); 709 SwPaM aCpyPam( aIdx ); //DocStart 710 711 // sind Tabellen-Formeln im Bereich, dann muss erst die Tabelle 712 // angezeigt werden, damit die Tabellen-Formel den neuen Wert errechnen 713 // kann (bei Bereichen wird sich ueber das Layout die einzelnen Boxen 714 // besorgt) 715 SwFieldType* pTblFldTyp = GetDoc()->GetSysFldType( RES_TABLEFLD ); 716 717 SwTableNode *pDestNd, *pSrcNd = aCpyPam.GetNode()->GetTableNode(); 718 if( !pSrcNd ) // TabellenNode ? 719 { // nicht ueberspringen!! 720 SwCntntNode* pCNd = aCpyPam.GetNode()->GetCntntNode(); 721 if( pCNd ) 722 aCpyPam.GetPoint()->nContent.Assign( pCNd, 0 ); 723 else if( !aCpyPam.Move( fnMoveForward, fnGoNode )) 724 aCpyPam.Move( fnMoveBackward, fnGoNode ); 725 } 726 727 aCpyPam.SetMark(); 728 aCpyPam.Move( fnMoveForward, fnGoDoc ); 729 730 sal_Bool bRet = sal_True, bDelTbl = sal_True; 731 StartAllAction(); 732 GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL ); 733 GetDoc()->LockExpFlds(); 734 735 // When the clipboard content has been created by a rectangular selection 736 // the pasting is more sophisticated: 737 // every paragraph will be inserted into another position. 738 // The first positions are given by the actual cursor ring, 739 // if there are more text portions to insert than cursor in this ring, 740 // the additional insert positions will be created by moving the last 741 // cursor position into the next line (like pressing the cursor down key) 742 if( pClpDoc->IsColumnSelection() && !IsTableMode() ) 743 { 744 // Creation of the list of insert positions 745 std::list< Insertion > aCopyList; 746 // The number of text portions of the rectangular selection 747 const sal_uInt32 nSelCount = aCpyPam.GetPoint()->nNode.GetIndex() 748 - aCpyPam.GetMark()->nNode.GetIndex(); 749 sal_uInt32 nCount = nSelCount; 750 SwNodeIndex aClpIdx( aIdx ); 751 SwPaM* pStartCursor = GetCrsr(); 752 SwPaM* pCurrCrsr = pStartCursor; 753 sal_uInt32 nCursorCount = pStartCursor->numberOf(); 754 // If the target selection is a multi-selection, often the last and first 755 // cursor of the ring points to identical document positions. Then 756 // we should avoid double insertion of text portions... 757 while( nCursorCount > 1 && *pCurrCrsr->GetPoint() == 758 *(dynamic_cast<SwPaM*>(pCurrCrsr->GetPrev())->GetPoint()) ) 759 { 760 --nCursorCount; 761 pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext()); 762 pStartCursor = pCurrCrsr; 763 } 764 SwPosition aStartPos( *pStartCursor->GetPoint() ); 765 SwPosition aInsertPos( aStartPos ); // first insertion position 766 bool bCompletePara = false; 767 sal_uInt16 nMove = 0; 768 while( nCount ) 769 { 770 --nCount; 771 ASSERT( aIdx.GetNode().GetCntntNode(), "Who filled the clipboard?!" ) 772 if( aIdx.GetNode().GetCntntNode() ) // robust 773 { 774 Insertion aInsertion( PaMPtr( new SwPaM( aIdx ) ), 775 PositionPtr( new SwPosition( aInsertPos ) ) ); 776 ++aIdx; 777 aInsertion.first->SetMark(); 778 if( pStartCursor == pCurrCrsr->GetNext() ) 779 { // Now we have to look for insertion positions... 780 if( !nMove ) // Annotate the last given insert position 781 aStartPos = aInsertPos; 782 SwCursor aCrsr( aStartPos, 0, false); 783 // Check if we find another insert position by moving 784 // down the last given position 785 if( aCrsr.UpDown( sal_False, ++nMove, 0, 0 ) ) 786 aInsertPos = *aCrsr.GetPoint(); 787 else // if there is no paragraph we have to create it 788 bCompletePara = nCount > 0; 789 nCursorCount = 0; 790 } 791 else // as long as we find more insert positions in the cursor ring 792 { // we'll take them 793 pCurrCrsr = dynamic_cast<SwPaM*>(pCurrCrsr->GetNext()); 794 aInsertPos = *pCurrCrsr->GetPoint(); 795 --nCursorCount; 796 } 797 // If there are no more paragraphs e.g. at the end of a document, 798 // we insert complete paragraphs instead of text portions 799 if( bCompletePara ) 800 aInsertion.first->GetPoint()->nNode = aIdx; 801 else 802 aInsertion.first->GetPoint()->nContent = 803 aInsertion.first->GetCntntNode()->Len(); 804 aCopyList.push_back( aInsertion ); 805 } 806 // If there are no text portions left but there are some more 807 // cursor positions to fill we have to restart with the first 808 // text portion 809 if( !nCount && nCursorCount ) 810 { 811 nCount = std::min( nSelCount, nCursorCount ); 812 aIdx = aClpIdx; // Start of clipboard content 813 } 814 } 815 std::list< Insertion >::const_iterator pCurr = aCopyList.begin(); 816 std::list< Insertion >::const_iterator pEnd = aCopyList.end(); 817 while( pCurr != pEnd ) 818 { 819 SwPosition& rInsPos = *pCurr->second; 820 SwPaM& rCopy = *pCurr->first; 821 const SwStartNode* pBoxNd = rInsPos.nNode.GetNode().FindTableBoxStartNode(); 822 if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex() && 823 rCopy.GetPoint()->nNode != rCopy.GetMark()->nNode ) 824 { 825 // if more than one node will be copied into a cell 826 // the box attributes have to be removed 827 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode ); 828 } 829 { 830 SwNodeIndex aIndexBefore(rInsPos.nNode); 831 aIndexBefore--; 832 pClpDoc->CopyRange( rCopy, rInsPos, false ); 833 { 834 aIndexBefore++; 835 SwPaM aPaM(SwPosition(aIndexBefore), 836 SwPosition(rInsPos.nNode)); 837 aPaM.GetDoc()->MakeUniqueNumRules(aPaM); 838 } 839 } 840 SaveTblBoxCntnt( &rInsPos ); 841 ++pCurr; 842 } 843 } 844 else 845 { 846 FOREACHPAM_START(this) 847 848 if( pSrcNd && 849 0 != ( pDestNd = GetDoc()->IsIdxInTbl( PCURCRSR->GetPoint()->nNode ))) 850 { 851 SwPosition aDestPos( *PCURCRSR->GetPoint() ); 852 853 sal_Bool bParkTblCrsr = sal_False; 854 const SwStartNode* pSttNd = PCURCRSR->GetNode()->FindTableBoxStartNode(); 855 856 // TABLE IN TABLE: Tabelle in Tabelle kopieren 857 // lasse ueber das Layout die Boxen suchen 858 SwSelBoxes aBoxes; 859 if( IsTableMode() ) // Tabellen-Selecktion ?? 860 { 861 GetTblSel( *this, aBoxes ); 862 ParkTblCrsr(); 863 bParkTblCrsr = sal_True; 864 } 865 else if( !PCURCRSR->HasMark() && PCURCRSR->GetNext() == PCURCRSR && 866 ( !pSrcNd->GetTable().IsTblComplex() || 867 pDestNd->GetTable().IsNewModel() ) ) 868 { 869 // dann die Tabelle "relativ" kopieren 870 SwTableBox* pBox = pDestNd->GetTable().GetTblBox( 871 pSttNd->GetIndex() ); 872 ASSERT( pBox, "Box steht nicht in dieser Tabelle" ); 873 aBoxes.Insert( pBox ); 874 } 875 876 SwNodeIndex aNdIdx( *pDestNd->EndOfSectionNode()); 877 if( !bParkTblCrsr ) 878 { 879 // erstmal aus der gesamten Tabelle raus 880 // ????? was ist mit Tabelle alleine im Rahmen ??????? 881 SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx ); 882 SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 )); 883 // #i59539: Don't remove all redline 884 SwPaM const tmpPaM(*pDestNd, *pDestNd->EndOfSectionNode()); 885 ::PaMCorrAbs(tmpPaM, aPos); 886 } 887 888 bRet = GetDoc()->InsCopyOfTbl( aDestPos, aBoxes, &pSrcNd->GetTable(), 889 sal_False, sal_False ); 890 891 if( bParkTblCrsr ) 892 GetCrsr(); 893 else 894 { 895 // und wieder in die Box zurueck 896 aNdIdx = *pSttNd; 897 SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aNdIdx ); 898 SwPosition aPos( aNdIdx, SwIndex( pCNd, 0 )); 899 // #i59539: Don't remove all redline 900 SwNode & rNode(PCURCRSR->GetPoint()->nNode.GetNode()); 901 SwCntntNode *const pCntntNode( rNode.GetCntntNode() ); 902 SwPaM const tmpPam(rNode, 0, 903 rNode, (pCntntNode) ? pCntntNode->Len() : 0); 904 ::PaMCorrAbs(tmpPam, aPos); 905 } 906 907 break; // aus der "while"-Schleife heraus 908 } 909 else if( *aCpyPam.GetPoint() == *aCpyPam.GetMark() && 910 pClpDoc->GetSpzFrmFmts()->Count() ) 911 { 912 // so langsam sollte mal eine DrawView erzeugt werden 913 if( !Imp()->GetDrawView() ) 914 MakeDrawView(); 915 916 for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i ) 917 { 918 sal_Bool bInsWithFmt = sal_True; 919 const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i]; 920 921 if( Imp()->GetDrawView()->IsGroupEntered() && 922 RES_DRAWFRMFMT == rCpyFmt.Which() && 923 (FLY_AS_CHAR != rCpyFmt.GetAnchor().GetAnchorId()) ) 924 { 925 const SdrObject* pSdrObj = rCpyFmt.FindSdrObject(); 926 if( pSdrObj ) 927 { 928 SdrObject* pNew = GetDoc()->CloneSdrObj( *pSdrObj, 929 sal_False, sal_False ); 930 931 // Insert object sets any anchor position to 0. 932 // Therefore we calculate the absolute position here 933 // and after the insert the anchor of the object 934 // is set to the anchor of the group object. 935 Rectangle aSnapRect = pNew->GetSnapRect(); 936 if( pNew->GetAnchorPos().X() || pNew->GetAnchorPos().Y() ) 937 { 938 const Point aPoint( 0, 0 ); 939 // OD 2004-04-05 #i26791# - direct drawing object 940 // positioning for group members 941 pNew->NbcSetAnchorPos( aPoint ); 942 pNew->NbcSetSnapRect( aSnapRect ); 943 } 944 945 Imp()->GetDrawView()->InsertObjectAtView( pNew, *Imp()->GetPageView() ); 946 947 Point aGrpAnchor( 0, 0 ); 948 SdrObjList* pList = pNew->GetObjList(); 949 if ( pList ) 950 { 951 SdrObject* pOwner = pList->GetOwnerObj(); 952 if ( pOwner ) 953 { 954 SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pOwner); 955 aGrpAnchor = pThisGroup->GetAnchorPos(); 956 } 957 } 958 959 // OD 2004-04-05 #i26791# - direct drawing object 960 // positioning for group members 961 pNew->NbcSetAnchorPos( aGrpAnchor ); 962 pNew->SetSnapRect( aSnapRect ); 963 964 bInsWithFmt = sal_False; 965 } 966 } 967 968 if( bInsWithFmt ) 969 { 970 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() ); 971 if ((FLY_AT_PARA == aAnchor.GetAnchorId()) || 972 (FLY_AT_CHAR == aAnchor.GetAnchorId()) || 973 (FLY_AS_CHAR == aAnchor.GetAnchorId())) 974 { 975 SwPosition* pPos = PCURCRSR->GetPoint(); 976 // #108784# allow shapes (no controls) in header/footer 977 if( RES_DRAWFRMFMT == rCpyFmt.Which() && 978 GetDoc()->IsInHeaderFooter( pPos->nNode ) && 979 CheckControlLayer( rCpyFmt.FindSdrObject() ) ) 980 continue; 981 982 aAnchor.SetAnchor( pPos ); 983 } 984 else if ( FLY_AT_PAGE == aAnchor.GetAnchorId() ) 985 { 986 aAnchor.SetPageNum( GetPhyPageNum() ); 987 } 988 else if( FLY_AT_FLY == aAnchor.GetAnchorId() ) 989 { 990 Point aPt; 991 lcl_SetAnchor( *PCURCRSR->GetPoint(), *PCURCRSR->GetNode(), 992 0, aPt, *this, aAnchor, aPt, sal_False ); 993 } 994 995 SwFrmFmt * pNew = GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true ); 996 997 if( pNew ) 998 { 999 if( RES_FLYFRMFMT == pNew->Which() ) 1000 { 1001 const Point aPt( GetCrsrDocPos() ); 1002 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pNew)-> 1003 GetFrm( &aPt, sal_False ); 1004 if( pFlyFrm ) 1005 SelectFlyFrm( *pFlyFrm, sal_True ); 1006 // immer nur den ersten Fly-Frame nehmen; die anderen 1007 // wurden ueber Fly in Fly ins ClipBoard kopiert ! 1008 break; 1009 } 1010 else 1011 { 1012 ASSERT( RES_DRAWFRMFMT == pNew->Which(), "Neues Format."); 1013 // --> OD 2005-09-01 #i52780# - drawing object has 1014 // to be made visible on paste. 1015 { 1016 SwDrawContact* pContact = 1017 static_cast<SwDrawContact*>(pNew->FindContactObj()); 1018 pContact->MoveObjToVisibleLayer( pContact->GetMaster() ); 1019 } 1020 // <-- 1021 SdrObject *pObj = pNew->FindSdrObject(); 1022 SwDrawView *pDV = Imp()->GetDrawView(); 1023 pDV->MarkObj( pObj, pDV->GetSdrPageView() ); 1024 // --> OD 2005-04-15 #i47455# - notify draw frame format 1025 // that position attributes are already set. 1026 if ( pNew->ISA(SwDrawFrmFmt) ) 1027 { 1028 static_cast<SwDrawFrmFmt*>(pNew)->PosAttrSet(); 1029 } 1030 // <-- 1031 } 1032 } 1033 } 1034 } 1035 } 1036 else 1037 { 1038 if( bDelTbl && IsTableMode() ) 1039 { 1040 SwEditShell::Delete(); 1041 bDelTbl = sal_False; 1042 } 1043 1044 SwPosition& rInsPos = *PCURCRSR->GetPoint(); 1045 const SwStartNode* pBoxNd = rInsPos.nNode.GetNode(). 1046 FindTableBoxStartNode(); 1047 if( pBoxNd && 2 == pBoxNd->EndOfSectionIndex() - 1048 pBoxNd->GetIndex() && 1049 aCpyPam.GetPoint()->nNode != aCpyPam.GetMark()->nNode ) 1050 { 1051 // es wird mehr als 1 Node in die akt. Box kopiert. Dann 1052 // muessen die BoxAttribute aber entfernt werden. 1053 GetDoc()->ClearBoxNumAttrs( rInsPos.nNode ); 1054 } 1055 //find out if the clipboard document starts with a table 1056 bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode(); 1057 SwPosition aInsertPosition( rInsPos ); 1058 1059 { 1060 SwNodeIndex aIndexBefore(rInsPos.nNode); 1061 1062 aIndexBefore--; 1063 1064 pClpDoc->CopyRange( aCpyPam, rInsPos, false ); 1065 1066 { 1067 aIndexBefore++; 1068 SwPaM aPaM(SwPosition(aIndexBefore), 1069 SwPosition(rInsPos.nNode)); 1070 1071 aPaM.GetDoc()->MakeUniqueNumRules(aPaM); 1072 } 1073 } 1074 1075 SaveTblBoxCntnt( &rInsPos ); 1076 if(bIncludingPageFrames && bStartWithTable) 1077 { 1078 //remove the paragraph in front of the table 1079 SwPaM aPara(aInsertPosition); 1080 GetDoc()->DelFullPara(aPara); 1081 } 1082 //additionally copy page bound frames 1083 if( bIncludingPageFrames && pClpDoc->GetSpzFrmFmts()->Count() ) 1084 { 1085 // create a draw view if necessary 1086 if( !Imp()->GetDrawView() ) 1087 MakeDrawView(); 1088 1089 for ( sal_uInt16 i = 0; i < pClpDoc->GetSpzFrmFmts()->Count(); ++i ) 1090 { 1091 sal_Bool bInsWithFmt = sal_True; 1092 const SwFrmFmt& rCpyFmt = *(*pClpDoc->GetSpzFrmFmts())[i]; 1093 if( bInsWithFmt ) 1094 { 1095 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() ); 1096 if ( FLY_AT_PAGE == aAnchor.GetAnchorId() ) 1097 { 1098 aAnchor.SetPageNum( aAnchor.GetPageNum() + nStartPageNumber - 1 ); 1099 } 1100 else 1101 continue; 1102 GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true ); 1103 } 1104 } 1105 } 1106 } 1107 1108 FOREACHPAM_END() 1109 } 1110 1111 GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_INSGLOSSARY, NULL ); 1112 1113 // wurden neue Tabellenformeln eingefuegt ? 1114 if( pTblFldTyp->GetDepends() ) 1115 { 1116 // alte Actions beenden; die Tabellen-Frames werden angelegt und 1117 // eine Selection kann erzeugt werden 1118 sal_uInt16 nActCnt; 1119 for( nActCnt = 0; ActionPend(); ++nActCnt ) 1120 EndAllAction(); 1121 1122 for( ; nActCnt; --nActCnt ) 1123 StartAllAction(); 1124 } 1125 GetDoc()->UnlockExpFlds(); 1126 GetDoc()->UpdateFlds(NULL, false); 1127 EndAllAction(); 1128 1129 return bRet; 1130 } 1131 1132 /*-- 14.06.2004 13:31:17--------------------------------------------------- 1133 1134 -----------------------------------------------------------------------*/ 1135 sal_Bool SwFEShell::PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage) 1136 { 1137 Push(); 1138 if(!GotoPage(nStartPage)) 1139 { 1140 Pop(sal_False); 1141 return sal_False; 1142 } 1143 MovePage( fnPageCurr, fnPageStart ); 1144 SwPaM aCpyPam( *GetCrsr()->GetPoint() ); 1145 String sStartingPageDesc = GetPageDesc( GetCurPageDesc()).GetName(); 1146 SwPageDesc* pDesc = rToFill.FindPageDescByName( sStartingPageDesc, sal_True ); 1147 if( pDesc ) 1148 rToFill.ChgCurPageDesc( *pDesc ); 1149 1150 if(!GotoPage(nEndPage)) 1151 { 1152 Pop(sal_False); 1153 return sal_False; 1154 } 1155 //if the page starts with a table a paragraph has to be inserted before 1156 SwNode* pTableNode = aCpyPam.GetNode()->FindTableNode(); 1157 if(pTableNode) 1158 { 1159 //insert a paragraph 1160 StartUndo(UNDO_INSERT); 1161 SwNodeIndex aTblIdx( *pTableNode, -1 ); 1162 SwPosition aBefore(aTblIdx); 1163 if(GetDoc()->AppendTxtNode( aBefore )) 1164 { 1165 SwPaM aTmp(aBefore); 1166 aCpyPam = aTmp; 1167 } 1168 EndUndo(UNDO_INSERT); 1169 } 1170 1171 MovePage( fnPageCurr, fnPageEnd ); 1172 aCpyPam.SetMark(); 1173 *aCpyPam.GetMark() = *GetCrsr()->GetPoint(); 1174 1175 SET_CURR_SHELL( this ); 1176 1177 StartAllAction(); 1178 GetDoc()->LockExpFlds(); 1179 SetSelection(aCpyPam); 1180 // copy the text of the selection 1181 SwEditShell::Copy(&rToFill); 1182 1183 if(pTableNode) 1184 { 1185 //remove the inserted paragraph 1186 Undo(); 1187 //remove the paragraph in the second doc, too 1188 SwNodeIndex aIdx( rToFill.GetDoc()->GetNodes().GetEndOfExtras(), 2 ); 1189 SwPaM aPara( aIdx ); //DocStart 1190 rToFill.GetDoc()->DelFullPara(aPara); 1191 } 1192 // now the page bound objects 1193 //additionally copy page bound frames 1194 if( GetDoc()->GetSpzFrmFmts()->Count() ) 1195 { 1196 // create a draw view if necessary 1197 if( !rToFill.Imp()->GetDrawView() ) 1198 rToFill.MakeDrawView(); 1199 1200 for ( sal_uInt16 i = 0; i < GetDoc()->GetSpzFrmFmts()->Count(); ++i ) 1201 { 1202 const SwFrmFmt& rCpyFmt = *(*GetDoc()->GetSpzFrmFmts())[i]; 1203 SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() ); 1204 if ((FLY_AT_PAGE == aAnchor.GetAnchorId()) && 1205 aAnchor.GetPageNum() >= nStartPage && aAnchor.GetPageNum() <= nEndPage) 1206 { 1207 aAnchor.SetPageNum( aAnchor.GetPageNum() - nStartPage + 1); 1208 } 1209 else 1210 continue; 1211 rToFill.GetDoc()->CopyLayoutFmt( rCpyFmt, aAnchor, true, true ); 1212 } 1213 } 1214 GetDoc()->UnlockExpFlds(); 1215 GetDoc()->UpdateFlds(NULL, false); 1216 Pop(sal_False); 1217 EndAllAction(); 1218 1219 return sal_True; 1220 } 1221 1222 sal_Bool SwFEShell::GetDrawObjGraphic( sal_uLong nFmt, Graphic& rGrf ) const 1223 { 1224 ASSERT( Imp()->HasDrawView(), "GetDrawObjGraphic without DrawView?" ); 1225 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); 1226 sal_Bool bConvert = sal_True; 1227 if( rMrkList.GetMarkCount() ) 1228 { 1229 if( rMrkList.GetMarkCount() == 1 && 1230 rMrkList.GetMark( 0 )->GetMarkedSdrObj()->ISA(SwVirtFlyDrawObj) ) 1231 { 1232 // Rahmen selektiert 1233 if( CNT_GRF == GetCntType() ) 1234 { 1235 // --> OD 2005-02-09 #119353# - robust 1236 const Graphic* pGrf( GetGraphic() ); 1237 if ( pGrf ) 1238 { 1239 Graphic aGrf( *pGrf ); 1240 if( SOT_FORMAT_GDIMETAFILE == nFmt ) 1241 { 1242 if( GRAPHIC_BITMAP != aGrf.GetType() ) 1243 { 1244 rGrf = aGrf; 1245 bConvert = sal_False; 1246 } 1247 else if( GetWin() ) 1248 { 1249 Size aSz; 1250 Point aPt; 1251 GetGrfSize( aSz ); 1252 1253 VirtualDevice aVirtDev; 1254 aVirtDev.EnableOutput( sal_False ); 1255 1256 MapMode aTmp( GetWin()->GetMapMode() ); 1257 aTmp.SetOrigin( aPt ); 1258 aVirtDev.SetMapMode( aTmp ); 1259 1260 GDIMetaFile aMtf; 1261 aMtf.Record( &aVirtDev ); 1262 aGrf.Draw( &aVirtDev, aPt, aSz ); 1263 aMtf.Stop(); 1264 aMtf.SetPrefMapMode( aTmp ); 1265 aMtf.SetPrefSize( aSz ); 1266 rGrf = aMtf; 1267 } 1268 } 1269 else if( GRAPHIC_BITMAP == aGrf.GetType() ) 1270 { 1271 rGrf = aGrf; 1272 bConvert = sal_False; 1273 } 1274 else 1275 { 1276 //fix(23806): Nicht die Originalgroesse, sondern die 1277 //aktuelle. Anderfalls kann es passieren, dass z.B. bei 1278 //Vektorgrafiken mal eben zig MB angefordert werden. 1279 const Size aSz( FindFlyFrm()->Prt().SSize() ); 1280 VirtualDevice aVirtDev( *GetWin() ); 1281 1282 MapMode aTmp( MAP_TWIP ); 1283 aVirtDev.SetMapMode( aTmp ); 1284 if( aVirtDev.SetOutputSize( aSz ) ) 1285 { 1286 aGrf.Draw( &aVirtDev, Point(), aSz ); 1287 rGrf = aVirtDev.GetBitmap( Point(), aSz ); 1288 } 1289 else 1290 { 1291 rGrf = aGrf; 1292 bConvert = sal_False; 1293 } 1294 } 1295 } 1296 // <-- 1297 } 1298 } 1299 else if( SOT_FORMAT_GDIMETAFILE == nFmt ) 1300 rGrf = Imp()->GetDrawView()->GetMarkedObjMetaFile(); 1301 else if( SOT_FORMAT_BITMAP == nFmt || SOT_FORMATSTR_ID_PNG == nFmt ) 1302 rGrf = Imp()->GetDrawView()->GetMarkedObjBitmapEx(); 1303 } 1304 return bConvert; 1305 } 1306 1307 // --> OD 2005-08-03 #i50824# 1308 // --> OD 2006-03-01 #b6382898# 1309 // replace method <lcl_RemoveOleObjsFromSdrModel> by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs> 1310 void lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SdrModel* _pModel ) 1311 { 1312 for ( sal_uInt16 nPgNum = 0; nPgNum < _pModel->GetPageCount(); ++nPgNum ) 1313 { 1314 // setup object iterator in order to iterate through all objects 1315 // including objects in group objects, but exclusive group objects. 1316 SdrObjListIter aIter(*(_pModel->GetPage( nPgNum ))); 1317 while( aIter.IsMore() ) 1318 { 1319 SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() ); 1320 if( pOle2Obj ) 1321 { 1322 // found an ole2 shape 1323 SdrObjList* pObjList = pOle2Obj->GetObjList(); 1324 1325 // get its graphic 1326 Graphic aGraphic; 1327 pOle2Obj->Connect(); 1328 Graphic* pGraphic = pOle2Obj->GetGraphic(); 1329 if( pGraphic ) 1330 aGraphic = *pGraphic; 1331 pOle2Obj->Disconnect(); 1332 1333 // create new graphic shape with the ole graphic and shape size 1334 SdrGrafObj* pGraphicObj = new SdrGrafObj( aGraphic, pOle2Obj->GetCurrentBoundRect() ); 1335 // apply layer of ole2 shape at graphic shape 1336 pGraphicObj->SetLayer( pOle2Obj->GetLayer() ); 1337 1338 // replace ole2 shape with the new graphic object and delete the ol2 shape 1339 SdrObject* pRemovedObject = pObjList->ReplaceObject( pGraphicObj, pOle2Obj->GetOrdNum() ); 1340 SdrObject::Free( pRemovedObject ); 1341 } 1342 } 1343 } 1344 } 1345 // <-- 1346 void SwFEShell::Paste( SvStream& rStrm, sal_uInt16 nAction, const Point* pPt ) 1347 { 1348 SET_CURR_SHELL( this ); 1349 StartAllAction(); 1350 StartUndo(); 1351 1352 SvtPathOptions aPathOpt; 1353 FmFormModel* pModel = new FmFormModel( aPathOpt.GetPalettePath(), 1354 0, GetDoc()->GetDocShell() ); 1355 pModel->GetItemPool().FreezeIdRanges(); 1356 1357 rStrm.Seek(0); 1358 1359 uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rStrm ) ); 1360 SvxDrawingLayerImport( pModel, xInputStream ); 1361 1362 if ( !Imp()->HasDrawView() ) 1363 Imp()->MakeDrawView(); 1364 1365 Point aPos( pPt ? *pPt : GetCharRect().Pos() ); 1366 SdrView *pView = Imp()->GetDrawView(); 1367 1368 //Drop auf bestehendes Objekt: Objekt ersetzen oder neu Attributieren. 1369 if( pModel->GetPageCount() > 0 && 1370 1 == pModel->GetPage(0)->GetObjCount() && 1371 1 == pView->GetMarkedObjectList().GetMarkCount() ) 1372 { 1373 // OD 10.07.2003 #110742# - replace a marked 'virtual' drawing object 1374 // by its corresponding 'master' drawing object in the mark list. 1375 SwDrawView::ReplaceMarkedDrawVirtObjs( *pView ); 1376 1377 SdrObject* pClpObj = pModel->GetPage(0)->GetObj(0); 1378 SdrObject* pOldObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj(); 1379 1380 if( SW_PASTESDR_SETATTR == nAction && pOldObj->ISA(SwVirtFlyDrawObj) ) 1381 nAction = SW_PASTESDR_REPLACE; 1382 1383 switch( nAction ) 1384 { 1385 case SW_PASTESDR_REPLACE: 1386 { 1387 const SwFrmFmt* pFmt(0); 1388 const SwFrm* pAnchor(0); 1389 if( pOldObj->ISA(SwVirtFlyDrawObj) ) 1390 { 1391 pFmt = FindFrmFmt( pOldObj ); 1392 1393 Point aNullPt; 1394 SwFlyFrm* pFlyFrm = ((SwFlyFrmFmt*)pFmt)->GetFrm( &aNullPt ); 1395 pAnchor = pFlyFrm->GetAnchorFrm(); 1396 1397 if( pAnchor->FindFooterOrHeader() ) 1398 { 1399 // wenn TextRahmen in der Kopf/Fusszeile steht, dann 1400 // nicht ersetzen, sondern nur einfuegen 1401 nAction = SW_PASTESDR_INSERT; 1402 break; 1403 } 1404 } 1405 1406 SdrObject* pNewObj = pClpObj->Clone(); 1407 Rectangle aOldObjRect( pOldObj->GetCurrentBoundRect() ); 1408 Size aOldObjSize( aOldObjRect.GetSize() ); 1409 Rectangle aNewRect( pNewObj->GetCurrentBoundRect() ); 1410 Size aNewSize( aNewRect.GetSize() ); 1411 1412 Fraction aScaleWidth( aOldObjSize.Width(), aNewSize.Width() ); 1413 Fraction aScaleHeight( aOldObjSize.Height(), aNewSize.Height()); 1414 pNewObj->NbcResize( aNewRect.TopLeft(), aScaleWidth, aScaleHeight); 1415 1416 Point aVec = aOldObjRect.TopLeft() - aNewRect.TopLeft(); 1417 pNewObj->NbcMove(Size(aVec.X(), aVec.Y())); 1418 1419 if( pNewObj->ISA( SdrUnoObj ) ) 1420 pNewObj->SetLayer( GetDoc()->GetControlsId() ); 1421 else if( pOldObj->ISA( SdrUnoObj ) ) 1422 pNewObj->SetLayer( GetDoc()->GetHeavenId() ); 1423 else 1424 pNewObj->SetLayer( pOldObj->GetLayer() ); 1425 1426 if( pOldObj->ISA(SwVirtFlyDrawObj) ) 1427 { 1428 // Attribute sichern und dam SdrObject setzen 1429 SfxItemSet aFrmSet( pDoc->GetAttrPool(), 1430 RES_SURROUND, RES_ANCHOR ); 1431 aFrmSet.Set( pFmt->GetAttrSet() ); 1432 1433 Point aNullPt; 1434 if( pAnchor->IsTxtFrm() && ((SwTxtFrm*)pAnchor)->IsFollow() ) 1435 { 1436 const SwTxtFrm* pTmp = (SwTxtFrm*)pAnchor; 1437 do { 1438 pTmp = pTmp->FindMaster(); 1439 ASSERT( pTmp, "Where's my Master?" ); 1440 } while( pTmp->IsFollow() ); 1441 pAnchor = pTmp; 1442 } 1443 if( pOldObj->ISA( SdrCaptionObj )) 1444 aNullPt = ((SdrCaptionObj*)pOldObj)->GetTailPos(); 1445 else 1446 aNullPt = aOldObjRect.TopLeft(); 1447 1448 Point aNewAnchor = pAnchor->GetFrmAnchorPos( ::HasWrap( pOldObj ) ); 1449 // OD 2004-04-05 #i26791# - direct positioning of Writer 1450 // fly frame object for <SwDoc::Insert(..)> 1451 pNewObj->NbcSetRelativePos( aNullPt - aNewAnchor ); 1452 pNewObj->NbcSetAnchorPos( aNewAnchor ); 1453 1454 pOldObj->GetOrdNum(); 1455 1456 DelSelectedObj(); 1457 1458 pFmt = GetDoc()->InsertDrawObj( *GetCrsr(), *pNewObj, aFrmSet ); 1459 } 1460 else 1461 { 1462 // #123922# for handling MasterObject and virtual ones correctly, SW 1463 // wants us to call ReplaceObject at the page, but that also 1464 // triggers the same assertion (I tried it), so stay at the view method 1465 pView->ReplaceObjectAtView(pOldObj, *Imp()->GetPageView(), pNewObj); 1466 } 1467 } 1468 break; 1469 1470 case SW_PASTESDR_SETATTR: 1471 { 1472 SfxItemSet aSet( GetAttrPool() ); 1473 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pClpObj); 1474 1475 if(pSdrGrafObj) 1476 { 1477 SdrObject* pTarget = 0; 1478 1479 if(0 != pView->GetMarkedObjectList().GetMarkCount()) 1480 { 1481 // try to get target (if it's at least one, take first) 1482 SdrMark* pMark = pView->GetMarkedObjectList().GetMark(0); 1483 1484 if(pMark) 1485 { 1486 pTarget = pMark->GetMarkedSdrObj(); 1487 } 1488 } 1489 1490 if(pTarget) 1491 { 1492 // copy ItemSet from target 1493 aSet.Set(pTarget->GetMergedItemSet()); 1494 } 1495 1496 // for SdrGrafObj, use the graphic as fill style argument 1497 const Graphic& rGraphic = pSdrGrafObj->GetGraphic(); 1498 1499 if(GRAPHIC_NONE != rGraphic.GetType() && GRAPHIC_DEFAULT != rGraphic.GetType()) 1500 { 1501 aSet.Put(XFillBitmapItem(String(), rGraphic)); 1502 aSet.Put(XFillStyleItem(XFILL_BITMAP)); 1503 } 1504 } 1505 else 1506 { 1507 aSet.Put(pClpObj->GetMergedItemSet()); 1508 } 1509 1510 pView->SetAttributes( aSet, sal_False ); 1511 } 1512 break; 1513 1514 default: 1515 nAction = SW_PASTESDR_INSERT; 1516 break; 1517 } 1518 } 1519 else 1520 nAction = SW_PASTESDR_INSERT; 1521 1522 if( SW_PASTESDR_INSERT == nAction ) 1523 { 1524 ::sw::DrawUndoGuard drawUndoGuard(GetDoc()->GetIDocumentUndoRedo()); 1525 1526 sal_Bool bDesignMode = pView->IsDesignMode(); 1527 if( !bDesignMode ) 1528 pView->SetDesignMode( sal_True ); 1529 1530 // --> OD 2005-08-03 #i50824# 1531 // --> OD 2006-03-01 #b6382898# 1532 // method <lcl_RemoveOleObjsFromSdrModel> replaced by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs> 1533 lcl_ConvertSdrOle2ObjsToSdrGrafObjs( pModel ); 1534 // <-- 1535 pView->Paste( *pModel, aPos ); 1536 1537 sal_uLong nCnt = pView->GetMarkedObjectList().GetMarkCount(); 1538 if( nCnt ) 1539 { 1540 const Point aNull( 0, 0 ); 1541 for( sal_uLong i=0; i < nCnt; ++i ) 1542 { 1543 SdrObject *pObj = pView->GetMarkedObjectList().GetMark(i)->GetMarkedSdrObj(); 1544 pObj->ImpSetAnchorPos( aNull ); 1545 } 1546 1547 pView->SetCurrentObj( OBJ_GRUP, SdrInventor ); 1548 if ( nCnt > 1 ) 1549 pView->GroupMarked(); 1550 SdrObject *pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); 1551 if( pObj->ISA( SdrUnoObj ) ) 1552 { 1553 pObj->SetLayer( GetDoc()->GetControlsId() ); 1554 bDesignMode = sal_True; 1555 } 1556 else 1557 pObj->SetLayer( GetDoc()->GetHeavenId() ); 1558 const Rectangle &rSnap = pObj->GetSnapRect(); 1559 const Size aDiff( rSnap.GetWidth()/2, rSnap.GetHeight()/2 ); 1560 pView->MoveMarkedObj( aDiff ); 1561 ImpEndCreate(); 1562 if( !bDesignMode ) 1563 pView->SetDesignMode( sal_False ); 1564 } 1565 } 1566 EndUndo(); 1567 EndAllAction(); 1568 delete pModel; 1569 } 1570 1571 bool SwFEShell::Paste( const Graphic &rGrf, const String& rURL ) 1572 { 1573 SET_CURR_SHELL( this ); 1574 SdrObject* pObj = 0; 1575 SdrView *pView = Imp()->GetDrawView(); 1576 1577 sal_Bool bRet = 1 == pView->GetMarkedObjectList().GetMarkCount() && 1578 (pObj = pView->GetMarkedObjectList().GetMark( 0 )->GetMarkedSdrObj())->IsClosedObj() && 1579 !pObj->ISA( SdrOle2Obj ); 1580 1581 if( bRet && pObj ) 1582 { 1583 // #123922# added code to handle the two cases of SdrGrafObj and a fillable, non- 1584 // OLE object in focus 1585 SdrObject* pResult = pObj; 1586 1587 if(dynamic_cast< SdrGrafObj* >(pObj)) 1588 { 1589 SdrGrafObj* pNewGrafObj = (SdrGrafObj*)pObj->Clone(); 1590 1591 pNewGrafObj->SetGraphic(rGrf); 1592 1593 // #123922# for handling MasterObject and virtual ones correctly, SW 1594 // wants us to call ReplaceObject at the page, but that also 1595 // triggers the same assertion (I tried it), so stay at the view method 1596 pView->ReplaceObjectAtView(pObj, *pView->GetSdrPageView(), pNewGrafObj); 1597 1598 // set in all cases - the Clone() will have copied an existing link (!) 1599 pNewGrafObj->SetGraphicLink(rURL, String()); 1600 1601 pResult = pNewGrafObj; 1602 } 1603 else 1604 { 1605 pView->AddUndo(new SdrUndoAttrObj(*pObj)); 1606 1607 SfxItemSet aSet(pView->GetModel()->GetItemPool(), XATTR_FILLSTYLE, XATTR_FILLBITMAP); 1608 1609 aSet.Put(XFillStyleItem(XFILL_BITMAP)); 1610 aSet.Put(XFillBitmapItem(String(), rGrf)); 1611 pObj->SetMergedItemSetAndBroadcast(aSet); 1612 } 1613 1614 // we are done; mark the modified/new object 1615 pView->MarkObj(pResult, pView->GetSdrPageView()); 1616 } 1617 1618 return bRet; 1619 } 1620