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