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_svx.hxx" 30 31 #include <vector> 32 #include <editeng/editeng.hxx> 33 #include "svx/xexch.hxx" 34 #include <svx/xflclit.hxx> 35 #include <svx/svdxcgv.hxx> 36 #include <svx/svdoutl.hxx> 37 #include "svx/svditext.hxx" 38 #include <svx/svdetc.hxx> 39 #include <svx/svdundo.hxx> 40 #include <svx/svdograf.hxx> 41 #include <svx/svdoole2.hxx> // fuer kein OLE im SdrClipboardFormat 42 #include <svx/svdorect.hxx> 43 #include <svx/svdoedge.hxx> // fuer Konnektoren uebers Clipboard 44 #include <svx/svdopage.hxx> // fuer Konnektoren uebers Clipboard 45 #include <svx/svdpage.hxx> 46 #include <svx/svdpagv.hxx> 47 #include <svx/svdtrans.hxx> // Fuer GetMapFactor zum umskalieren bei PasteModel 48 #include "svx/svdstr.hrc" // Namen aus der Resource 49 #include "svx/svdglob.hxx" // StringCache 50 #include "svx/xoutbmp.hxx" 51 #include <vcl/metaact.hxx> 52 #include <svl/poolitem.hxx> 53 #include <svl/itempool.hxx> 54 #include <tools/bigint.hxx> 55 #include <sot/formats.hxx> 56 57 // #i13033# 58 #include <clonelist.hxx> 59 #include <vcl/virdev.hxx> 60 61 // b4967543 62 #include <svl/style.hxx> 63 64 // #i72535# 65 #include "fmobj.hxx" 66 67 //////////////////////////////////////////////////////////////////////////////////////////////////// 68 69 SdrExchangeView::SdrExchangeView(SdrModel* pModel1, OutputDevice* pOut): 70 SdrObjEditView(pModel1,pOut) 71 { 72 } 73 74 //////////////////////////////////////////////////////////////////////////////////////////////////// 75 76 Point SdrExchangeView::GetViewCenter(const OutputDevice* pOut) const 77 { 78 Point aCenter; 79 if (pOut==NULL) 80 { 81 pOut = GetFirstOutputDevice(); 82 } 83 if (pOut!=NULL) { 84 Point aOfs=pOut->GetMapMode().GetOrigin(); 85 Size aOutSiz=pOut->GetOutputSize(); 86 aOutSiz.Width()/=2; 87 aOutSiz.Height()/=2; 88 aCenter.X()=aOutSiz.Width() -aOfs.X(); 89 aCenter.Y()=aOutSiz.Height()-aOfs.Y(); 90 } 91 return aCenter; 92 } 93 94 Point SdrExchangeView::GetPastePos(SdrObjList* pLst, OutputDevice* pOut) 95 { 96 Point aP(GetViewCenter(pOut)); 97 SdrPage* pPg=NULL; 98 if (pLst!=NULL) pPg=pLst->GetPage(); 99 if (pPg!=NULL) { 100 Size aSiz(pPg->GetSize()); 101 aP.X()=aSiz.Width()/2; 102 aP.Y()=aSiz.Height()/2; 103 } 104 return aP; 105 } 106 107 sal_Bool SdrExchangeView::ImpLimitToWorkArea(Point& rPt) const 108 { 109 sal_Bool bRet(sal_False); 110 111 if(!aMaxWorkArea.IsEmpty()) 112 { 113 if(rPt.X()<aMaxWorkArea.Left()) 114 { 115 rPt.X() = aMaxWorkArea.Left(); 116 bRet = sal_True; 117 } 118 119 if(rPt.X()>aMaxWorkArea.Right()) 120 { 121 rPt.X() = aMaxWorkArea.Right(); 122 bRet = sal_True; 123 } 124 125 if(rPt.Y()<aMaxWorkArea.Top()) 126 { 127 rPt.Y() = aMaxWorkArea.Top(); 128 bRet = sal_True; 129 } 130 131 if(rPt.Y()>aMaxWorkArea.Bottom()) 132 { 133 rPt.Y() = aMaxWorkArea.Bottom(); 134 bRet = sal_True; 135 } 136 } 137 return bRet; 138 } 139 140 void SdrExchangeView::ImpGetPasteObjList(Point& /*rPos*/, SdrObjList*& rpLst) 141 { 142 if (rpLst==NULL) 143 { 144 SdrPageView* pPV = GetSdrPageView(); 145 146 if (pPV!=NULL) { 147 rpLst=pPV->GetObjList(); 148 } 149 } 150 } 151 152 sal_Bool SdrExchangeView::ImpGetPasteLayer(const SdrObjList* pObjList, SdrLayerID& rLayer) const 153 { 154 sal_Bool bRet=sal_False; 155 rLayer=0; 156 if (pObjList!=NULL) { 157 const SdrPage* pPg=pObjList->GetPage(); 158 if (pPg!=NULL) { 159 rLayer=pPg->GetLayerAdmin().GetLayerID(aAktLayer,sal_True); 160 if (rLayer==SDRLAYER_NOTFOUND) rLayer=0; 161 SdrPageView* pPV = GetSdrPageView(); 162 if (pPV!=NULL) { 163 bRet=!pPV->GetLockedLayers().IsSet(rLayer) && pPV->GetVisibleLayers().IsSet(rLayer); 164 } 165 } 166 } 167 return bRet; 168 } 169 170 //////////////////////////////////////////////////////////////////////////////////////////////////// 171 172 sal_Bool SdrExchangeView::Paste(const GDIMetaFile& rMtf, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions) 173 { 174 Point aPos(rPos); 175 ImpGetPasteObjList(aPos,pLst); 176 ImpLimitToWorkArea( aPos ); 177 if (pLst==NULL) return sal_False; 178 SdrLayerID nLayer; 179 if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False; 180 sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit(); 181 if (bUnmark) UnmarkAllObj(); 182 SdrGrafObj* pObj=new SdrGrafObj(Graphic(rMtf)); 183 pObj->SetLayer(nLayer); 184 ImpPasteObject(pObj,*pLst,aPos,rMtf.GetPrefSize(),rMtf.GetPrefMapMode(),nOptions); 185 return sal_True; 186 } 187 188 sal_Bool SdrExchangeView::Paste(const Bitmap& rBmp, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions) 189 { 190 Point aPos(rPos); 191 ImpGetPasteObjList(aPos,pLst); 192 ImpLimitToWorkArea( aPos ); 193 if (pLst==NULL) return sal_False; 194 SdrLayerID nLayer; 195 if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False; 196 sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit(); 197 if (bUnmark) UnmarkAllObj(); 198 SdrGrafObj* pObj=new SdrGrafObj(Graphic(rBmp)); 199 pObj->SetLayer(nLayer); 200 ImpPasteObject(pObj,*pLst,aPos,rBmp.GetSizePixel(),MapMode(MAP_PIXEL),nOptions); 201 return sal_True; 202 } 203 204 sal_Bool SdrExchangeView::Paste(const XubString& rStr, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions) 205 { 206 if(!rStr.Len()) 207 return sal_False; 208 209 Point aPos(rPos); 210 ImpGetPasteObjList(aPos,pLst); 211 ImpLimitToWorkArea( aPos ); 212 if (pLst==NULL) return sal_False; 213 SdrLayerID nLayer; 214 if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False; 215 sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit(); 216 if (bUnmark) UnmarkAllObj(); 217 Rectangle aTextRect(0,0,500,500); 218 SdrPage* pPage=pLst->GetPage(); 219 if (pPage!=NULL) { 220 aTextRect.SetSize(pPage->GetSize()); 221 } 222 SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect); 223 pObj->SetModel(pMod); 224 pObj->SetLayer(nLayer); 225 pObj->NbcSetText(rStr); // #32424# SetText vor SetAttr, weil SetAttr sonst unwirksam! 226 if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False); 227 228 pObj->SetMergedItemSet(aDefaultAttr); 229 230 SfxItemSet aTempAttr(pMod->GetItemPool()); // Keine Fuellung oder Linie 231 aTempAttr.Put(XLineStyleItem(XLINE_NONE)); 232 aTempAttr.Put(XFillStyleItem(XFILL_NONE)); 233 234 pObj->SetMergedItemSet(aTempAttr); 235 236 pObj->FitFrameToTextSize(); 237 Size aSiz(pObj->GetLogicRect().GetSize()); 238 MapUnit eMap=pMod->GetScaleUnit(); 239 Fraction aMap=pMod->GetScaleFraction(); 240 ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions); 241 return sal_True; 242 } 243 244 sal_Bool SdrExchangeView::Paste(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions) 245 { 246 Point aPos(rPos); 247 ImpGetPasteObjList(aPos,pLst); 248 ImpLimitToWorkArea( aPos ); 249 if (pLst==NULL) return sal_False; 250 SdrLayerID nLayer; 251 if (!ImpGetPasteLayer(pLst,nLayer)) return sal_False; 252 sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit(); 253 if (bUnmark) UnmarkAllObj(); 254 Rectangle aTextRect(0,0,500,500); 255 SdrPage* pPage=pLst->GetPage(); 256 if (pPage!=NULL) { 257 aTextRect.SetSize(pPage->GetSize()); 258 } 259 SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect); 260 pObj->SetModel(pMod); 261 pObj->SetLayer(nLayer); 262 if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False); 263 264 pObj->SetMergedItemSet(aDefaultAttr); 265 266 SfxItemSet aTempAttr(pMod->GetItemPool()); // Keine Fuellung oder Linie 267 aTempAttr.Put(XLineStyleItem(XLINE_NONE)); 268 aTempAttr.Put(XFillStyleItem(XFILL_NONE)); 269 270 pObj->SetMergedItemSet(aTempAttr); 271 272 pObj->NbcSetText(rInput,rBaseURL,eFormat); 273 pObj->FitFrameToTextSize(); 274 Size aSiz(pObj->GetLogicRect().GetSize()); 275 MapUnit eMap=pMod->GetScaleUnit(); 276 Fraction aMap=pMod->GetScaleFraction(); 277 ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions); 278 279 // b4967543 280 if(pObj && pObj->GetModel() && pObj->GetOutlinerParaObject()) 281 { 282 SdrOutliner& rOutliner = pObj->GetModel()->GetHitTestOutliner(); 283 rOutliner.SetText(*pObj->GetOutlinerParaObject()); 284 285 if(1L == rOutliner.GetParagraphCount()) 286 { 287 SfxStyleSheet* pCandidate = rOutliner.GetStyleSheet(0L); 288 289 if(pCandidate) 290 { 291 if(pObj->GetModel()->GetStyleSheetPool() == &pCandidate->GetPool()) 292 { 293 pObj->NbcSetStyleSheet(pCandidate, sal_True); 294 } 295 } 296 } 297 } 298 299 return sal_True; 300 } 301 302 sal_Bool SdrExchangeView::Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions) 303 { 304 const SdrModel* pSrcMod=&rMod; 305 if (pSrcMod==pMod) 306 return sal_False; // na so geht's ja nun nicht 307 308 const bool bUndo = IsUndoEnabled(); 309 310 if( bUndo ) 311 BegUndo(ImpGetResStr(STR_ExchangePaste)); 312 313 if( mxSelectionController.is() && mxSelectionController->PasteObjModel( rMod ) ) 314 { 315 if( bUndo ) 316 EndUndo(); 317 return sal_True; 318 } 319 320 Point aPos(rPos); 321 ImpGetPasteObjList(aPos,pLst); 322 SdrPageView* pMarkPV=NULL; 323 SdrPageView* pPV = GetSdrPageView(); 324 325 if(pPV) 326 { 327 if ( pPV->GetObjList() == pLst ) 328 pMarkPV=pPV; 329 } 330 331 ImpLimitToWorkArea( aPos ); 332 if (pLst==NULL) 333 return sal_False; 334 335 sal_Bool bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit(); 336 if (bUnmark) 337 UnmarkAllObj(); 338 339 // evtl. umskalieren bei unterschiedlicher MapUnit am Model 340 // Dafuer erstmal die Faktoren berechnen 341 MapUnit eSrcUnit=pSrcMod->GetScaleUnit(); 342 MapUnit eDstUnit=pMod->GetScaleUnit(); 343 sal_Bool bResize=eSrcUnit!=eDstUnit; 344 Fraction xResize,yResize; 345 Point aPt0; 346 if (bResize) 347 { 348 FrPair aResize(GetMapFactor(eSrcUnit,eDstUnit)); 349 xResize=aResize.X(); 350 yResize=aResize.Y(); 351 } 352 SdrObjList* pDstLst=pLst; 353 sal_uInt16 nPg,nPgAnz=pSrcMod->GetPageCount(); 354 for (nPg=0; nPg<nPgAnz; nPg++) 355 { 356 const SdrPage* pSrcPg=pSrcMod->GetPage(nPg); 357 358 // #104148# Use SnapRect, not BoundRect here 359 Rectangle aR=pSrcPg->GetAllObjSnapRect(); 360 361 if (bResize) 362 ResizeRect(aR,aPt0,xResize,yResize); 363 Point aDist(aPos-aR.Center()); 364 Size aSiz(aDist.X(),aDist.Y()); 365 //sal_uIntPtr nDstObjAnz0=pDstLst->GetObjCount(); 366 sal_uIntPtr nCloneErrCnt=0; 367 sal_uIntPtr nOb,nObAnz=pSrcPg->GetObjCount(); 368 sal_Bool bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0; 369 370 // #i13033# 371 // New mechanism to re-create the connections of cloned connectors 372 CloneList aCloneList; 373 374 for (nOb=0; nOb<nObAnz; nOb++) 375 { 376 const SdrObject* pSrcOb=pSrcPg->GetObj(nOb); 377 378 // #116235# 379 SdrObject* pNeuObj = pSrcOb->Clone(); 380 381 if (pNeuObj!=NULL) 382 { 383 if(bResize) 384 { 385 pNeuObj->GetModel()->SetPasteResize(sal_True); // #51139# 386 pNeuObj->NbcResize(aPt0,xResize,yResize); 387 pNeuObj->GetModel()->SetPasteResize(sal_False); // #51139# 388 } 389 390 // #i39861# 391 pNeuObj->SetModel(pDstLst->GetModel()); 392 pNeuObj->SetPage(pDstLst->GetPage()); 393 394 pNeuObj->NbcMove(aSiz); 395 396 const SdrPage* pPg = pDstLst->GetPage(); 397 398 if(pPg) 399 { 400 // #i72535# 401 const SdrLayerAdmin& rAd = pPg->GetLayerAdmin(); 402 SdrLayerID nLayer(0); 403 404 if(pNeuObj->ISA(FmFormObj)) 405 { 406 // for FormControls, force to form layer 407 nLayer = rAd.GetLayerID(rAd.GetControlLayerName(), true); 408 } 409 else 410 { 411 nLayer = rAd.GetLayerID(aAktLayer, sal_True); 412 } 413 414 if(SDRLAYER_NOTFOUND == nLayer) 415 { 416 nLayer = 0; 417 } 418 419 pNeuObj->SetLayer(nLayer); 420 } 421 422 SdrInsertReason aReason(SDRREASON_VIEWCALL); 423 pDstLst->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason); 424 425 if( bUndo ) 426 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNeuObj)); 427 428 if (bMark) { 429 // Markhandles noch nicht sofort setzen! 430 // Das erledigt das ModelHasChanged der MarkView. 431 MarkObj(pNeuObj,pMarkPV,sal_False,sal_True); 432 } 433 434 // #i13033# 435 aCloneList.AddPair(pSrcOb, pNeuObj); 436 } 437 else 438 { 439 nCloneErrCnt++; 440 } 441 } 442 443 // #i13033# 444 // New mechanism to re-create the connections of cloned connectors 445 aCloneList.CopyConnections(); 446 447 if(0L != nCloneErrCnt) 448 { 449 #ifdef DBG_UTIL 450 ByteString aStr("SdrExchangeView::Paste(): Fehler beim Clonen "); 451 452 if(nCloneErrCnt == 1) 453 { 454 aStr += "eines Zeichenobjekts."; 455 } 456 else 457 { 458 aStr += "von "; 459 aStr += ByteString::CreateFromInt32( nCloneErrCnt ); 460 aStr += " Zeichenobjekten."; 461 } 462 463 aStr += " Objektverbindungen werden nicht mitkopiert."; 464 465 DBG_ERROR(aStr.GetBuffer()); 466 #endif 467 } 468 } 469 470 if( bUndo ) 471 EndUndo(); 472 473 return sal_True; 474 } 475 476 sal_Bool SdrExchangeView::IsExchangeFormatSupported(sal_uIntPtr nFormat) const 477 { 478 return( FORMAT_PRIVATE == nFormat || 479 FORMAT_GDIMETAFILE == nFormat || 480 FORMAT_BITMAP == nFormat || 481 FORMAT_RTF == nFormat || 482 FORMAT_STRING == nFormat || 483 SOT_FORMATSTR_ID_DRAWING == nFormat || 484 SOT_FORMATSTR_ID_EDITENGINE == nFormat ); 485 } 486 487 void SdrExchangeView::ImpPasteObject(SdrObject* pObj, SdrObjList& rLst, const Point& rCenter, const Size& rSiz, const MapMode& rMap, sal_uInt32 nOptions) 488 { 489 BigInt nSizX(rSiz.Width()); 490 BigInt nSizY(rSiz.Height()); 491 MapUnit eSrcMU=rMap.GetMapUnit(); 492 MapUnit eDstMU=pMod->GetScaleUnit(); 493 FrPair aMapFact(GetMapFactor(eSrcMU,eDstMU)); 494 Fraction aDstFr(pMod->GetScaleFraction()); 495 nSizX*=aMapFact.X().GetNumerator(); 496 nSizX*=rMap.GetScaleX().GetNumerator(); 497 nSizX*=aDstFr.GetDenominator(); 498 nSizX/=aMapFact.X().GetDenominator(); 499 nSizX/=rMap.GetScaleX().GetDenominator(); 500 nSizX/=aDstFr.GetNumerator(); 501 nSizY*=aMapFact.Y().GetNumerator(); 502 nSizY*=rMap.GetScaleY().GetNumerator(); 503 nSizX*=aDstFr.GetDenominator(); 504 nSizY/=aMapFact.Y().GetDenominator(); 505 nSizY/=rMap.GetScaleY().GetDenominator(); 506 nSizY/=aDstFr.GetNumerator(); 507 long xs=nSizX; 508 long ys=nSizY; 509 Point aPos(rCenter.X()-xs/2,rCenter.Y()-ys/2); 510 Rectangle aR(aPos.X(),aPos.Y(),aPos.X()+xs,aPos.Y()+ys); 511 pObj->SetLogicRect(aR); 512 SdrInsertReason aReason(SDRREASON_VIEWCALL); 513 rLst.InsertObject(pObj,CONTAINER_APPEND,&aReason); 514 515 if( IsUndoEnabled() ) 516 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj)); 517 518 SdrPageView* pMarkPV=NULL; 519 SdrPageView* pPV = GetSdrPageView(); 520 521 if(pPV) 522 { 523 if (pPV->GetObjList()==&rLst) 524 pMarkPV=pPV; 525 } 526 527 sal_Bool bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0; 528 if (bMark) 529 { // Obj in der ersten gefundenen PageView markieren 530 MarkObj(pObj,pMarkPV); 531 } 532 } 533 534 //////////////////////////////////////////////////////////////////////////////////////////////////// 535 536 Bitmap SdrExchangeView::GetMarkedObjBitmap( sal_Bool bNoVDevIfOneBmpMarked ) const 537 { 538 Bitmap aBmp; 539 540 if( AreObjectsMarked() ) 541 { 542 if( bNoVDevIfOneBmpMarked ) 543 { 544 SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 ); 545 SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL; 546 547 if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) ) 548 aBmp = pGrafObj->GetTransformedGraphic().GetBitmap(); 549 } 550 551 if( !aBmp ) 552 { 553 const Graphic aGraphic( GetMarkedObjMetaFile( bNoVDevIfOneBmpMarked ) ); 554 555 // #i102089# support user's settings of AA and LineSnap when the MetaFile gets 556 // rasterconverted to a bitmap 557 const SvtOptionsDrawinglayer aDrawinglayerOpt; 558 const GraphicConversionParameters aParameters( 559 Size(), 560 false, 561 aDrawinglayerOpt.IsAntiAliasing(), 562 aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete()); 563 564 aBmp = aGraphic.GetBitmap(aParameters); 565 } 566 } 567 568 return aBmp; 569 } 570 571 // ----------------------------------------------------------------------------- 572 573 GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile( sal_Bool bNoVDevIfOneMtfMarked ) const 574 { 575 GDIMetaFile aMtf; 576 577 if( AreObjectsMarked() ) 578 { 579 Rectangle aBound( GetMarkedObjBoundRect() ); 580 Size aBoundSize( aBound.GetWidth(), aBound.GetHeight() ); 581 MapMode aMap( pMod->GetScaleUnit(), Point(), pMod->GetScaleFraction(), pMod->GetScaleFraction() ); 582 583 if( bNoVDevIfOneMtfMarked ) 584 { 585 SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 ); 586 SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() ==1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL; 587 588 if( pGrafObj ) 589 { 590 Graphic aGraphic( pGrafObj->GetTransformedGraphic() ); 591 592 if( aGraphic.GetType() == GRAPHIC_BITMAP ) 593 { 594 const Point aPos; 595 596 aMtf.AddAction( new MetaBmpExScaleAction( aPos, aBoundSize, aGraphic.GetBitmapEx() ) ); 597 aMtf.SetPrefMapMode( aMap ); 598 aMtf.SetPrefSize( aBoundSize ); 599 } 600 else 601 aMtf = aGraphic.GetGDIMetaFile(); 602 } 603 } 604 605 if( !aMtf.GetActionCount() ) 606 { 607 VirtualDevice aOut; 608 Size aDummySize( 2, 2 ); 609 610 aOut.SetOutputSizePixel( aDummySize ); 611 aOut.EnableOutput( sal_False ); 612 aOut.SetMapMode( aMap ); 613 614 aMtf.Clear(); 615 aMtf.Record( &aOut ); 616 617 // Replace offset given formally to DrawMarkedObj and used at XOutDev with relative 618 // MapMode (which was also used in XOutDev in that case). Goal is to paint the object 619 // as if TopLeft point is (0,0) 620 const Fraction aNeutralFraction(1, 1); 621 const MapMode aRelativeMapMode(MAP_RELATIVE, Point(-aBound.Left(), -aBound.Top()), aNeutralFraction, aNeutralFraction); 622 aOut.SetMapMode(aRelativeMapMode); 623 624 DrawMarkedObj(aOut); 625 626 aMtf.Stop(); 627 aMtf.WindStart(); 628 aMtf.SetPrefMapMode( aMap ); 629 630 // removed PrefSize extension. It is principially wrong to set a reduced size at 631 // the created MetaFile. The mentioned errors occurr at output time since the integer 632 // MapModes from VCL lead to errors. It is now corrected in the VCLRenderer for 633 // primitives (and may later be done in breaking up a MetaFile to primitives) 634 aMtf.SetPrefSize(aBoundSize); 635 } 636 } 637 638 return aMtf; 639 } 640 641 // ----------------------------------------------------------------------------- 642 643 Graphic SdrExchangeView::GetAllMarkedGraphic() const 644 { 645 Graphic aRet; 646 647 if( AreObjectsMarked() ) 648 { 649 if( ( 1 == GetMarkedObjectCount() ) && GetSdrMarkByIndex( 0 ) ) 650 aRet = SdrExchangeView::GetObjGraphic( pMod, GetMarkedObjectByIndex( 0 ) ); 651 else 652 aRet = GetMarkedObjMetaFile( sal_False ); 653 } 654 655 return aRet; 656 } 657 658 // ----------------------------------------------------------------------------- 659 660 Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject* pObj ) 661 { 662 Graphic aRet; 663 664 if( pModel && pObj ) 665 { 666 // try to get a graphic from the object first 667 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj); 668 const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj); 669 670 if(pSdrGrafObj) 671 { 672 // #110981# Make behaviour coherent with metafile 673 // recording below (which of course also takes 674 // view-transformed objects) 675 aRet = pSdrGrafObj->GetTransformedGraphic(); 676 } 677 else if(pSdrOle2Obj) 678 { 679 if ( pSdrOle2Obj->GetGraphic() ) 680 aRet = *pSdrOle2Obj->GetGraphic(); 681 } 682 683 // if graphic could not be retrieved => go the hard way and create a MetaFile 684 if( ( GRAPHIC_NONE == aRet.GetType() ) || ( GRAPHIC_DEFAULT == aRet.GetType() ) ) 685 { 686 VirtualDevice aOut; 687 GDIMetaFile aMtf; 688 const Rectangle aBoundRect( pObj->GetCurrentBoundRect() ); 689 const MapMode aMap( pModel->GetScaleUnit(), 690 Point(), 691 pModel->GetScaleFraction(), 692 pModel->GetScaleFraction() ); 693 694 aOut.EnableOutput( sal_False ); 695 aOut.SetMapMode( aMap ); 696 aMtf.Record( &aOut ); 697 pObj->SingleObjectPainter( aOut ); // #110094#-17 698 aMtf.Stop(); 699 aMtf.WindStart(); 700 701 // #i99268# replace the original offset from using XOutDev's SetOffset 702 // NOT (as tried with #i92760#) with another MapMode which gets recorded 703 // by the Metafile itself (what always leads to problems), but by hardly 704 // moving the result 705 aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top()); 706 707 aMtf.SetPrefMapMode( aMap ); 708 aMtf.SetPrefSize( aBoundRect.GetSize() ); 709 710 if( aMtf.GetActionCount() ) 711 aRet = aMtf; 712 } 713 } 714 715 return aRet; 716 } 717 718 // ----------------------------------------------------------------------------- 719 720 void SdrExchangeView::DrawMarkedObj(OutputDevice& rOut) const 721 { 722 SortMarkedObjects(); 723 724 ::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 ); 725 ::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ]; 726 ::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ]; 727 const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin(); 728 const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False ); 729 sal_uInt32 n, nCount; 730 731 for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ ) 732 { 733 SdrMark* pMark = GetSdrMarkByIndex( n ); 734 735 // paint objects on control layer on top of all otherobjects 736 if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() ) 737 rObjVector2.push_back( pMark ); 738 else 739 rObjVector1.push_back( pMark ); 740 } 741 742 for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ ) 743 { 744 ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ]; 745 746 for( sal_uInt32 i = 0; i < rObjVector.size(); i++ ) 747 { 748 SdrMark* pMark = rObjVector[ i ]; 749 pMark->GetMarkedSdrObj()->SingleObjectPainter( rOut ); // #110094#-17 750 } 751 } 752 } 753 754 // ----------------------------------------------------------------------------- 755 756 SdrModel* SdrExchangeView::GetMarkedObjModel() const 757 { 758 // Wenn das sortieren der MarkList mal stoeren sollte, 759 // werde ich sie mir wohl kopieren muessen. 760 SortMarkedObjects(); 761 SdrModel* pNeuMod=pMod->AllocModel(); 762 SdrPage* pNeuPag=pNeuMod->AllocPage(sal_False); 763 pNeuMod->InsertPage(pNeuPag); 764 765 if( !mxSelectionController.is() || !mxSelectionController->GetMarkedObjModel( pNeuPag ) ) 766 { 767 ::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 ); 768 ::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ]; 769 ::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ]; 770 const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin(); 771 const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False ); 772 sal_uInt32 n, nCount, nCloneErrCnt = 0; 773 774 for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ ) 775 { 776 SdrMark* pMark = GetSdrMarkByIndex( n ); 777 778 // paint objects on control layer on top of all otherobjects 779 if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() ) 780 rObjVector2.push_back( pMark ); 781 else 782 rObjVector1.push_back( pMark ); 783 } 784 785 // #i13033# 786 // New mechanism to re-create the connections of cloned connectors 787 CloneList aCloneList; 788 789 for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ ) 790 { 791 ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ]; 792 793 for( sal_uInt32 i = 0; i < rObjVector.size(); i++ ) 794 { 795 const SdrMark* pMark = rObjVector[ i ]; 796 const SdrObject* pObj = pMark->GetMarkedSdrObj(); 797 SdrObject* pNeuObj; 798 799 if( pObj->ISA( SdrPageObj ) ) 800 { 801 // convert SdrPageObj's to a graphic representation, because 802 // virtual connection to referenced page gets lost in new model 803 pNeuObj = new SdrGrafObj( GetObjGraphic( pMod, pObj ), pObj->GetLogicRect() ); 804 pNeuObj->SetPage( pNeuPag ); 805 pNeuObj->SetModel( pNeuMod ); 806 } 807 else 808 { 809 // #116235# 810 // pNeuObj = pObj->Clone( pNeuPag, pNeuMod ); 811 pNeuObj = pObj->Clone(); 812 pNeuObj->SetPage( pNeuPag ); 813 pNeuObj->SetModel( pNeuMod ); 814 } 815 816 if( pNeuObj ) 817 { 818 SdrInsertReason aReason(SDRREASON_VIEWCALL); 819 pNeuPag->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason); 820 821 // #i13033# 822 aCloneList.AddPair(pObj, pNeuObj); 823 } 824 else 825 nCloneErrCnt++; 826 } 827 } 828 829 // #i13033# 830 // New mechanism to re-create the connections of cloned connectors 831 aCloneList.CopyConnections(); 832 833 if(0L != nCloneErrCnt) 834 { 835 #ifdef DBG_UTIL 836 ByteString aStr("SdrExchangeView::GetMarkedObjModel(): Fehler beim Clonen "); 837 838 if(nCloneErrCnt == 1) 839 { 840 aStr += "eines Zeichenobjekts."; 841 } 842 else 843 { 844 aStr += "von "; 845 aStr += ByteString::CreateFromInt32( nCloneErrCnt ); 846 aStr += " Zeichenobjekten."; 847 } 848 849 aStr += " Objektverbindungen werden nicht mitkopiert."; 850 851 DBG_ERROR(aStr.GetBuffer()); 852 #endif 853 } 854 } 855 return pNeuMod; 856 } 857 858 // ----------------------------------------------------------------------------- 859 860 sal_Bool SdrExchangeView::Cut( sal_uIntPtr /*nFormat */) 861 { 862 DBG_ERROR( "SdrExchangeView::Cut: Not supported anymore" ); 863 return sal_False; 864 } 865 866 // ----------------------------------------------------------------------------- 867 868 void SdrExchangeView::CutMarked( sal_uIntPtr /*nFormat */) 869 { 870 DBG_ERROR( "SdrExchangeView::CutMarked: Not supported anymore" ); 871 } 872 873 // ----------------------------------------------------------------------------- 874 875 sal_Bool SdrExchangeView::Yank(sal_uIntPtr /*nFormat*/) 876 { 877 DBG_ERROR( "SdrExchangeView::Yank: Not supported anymore" ); 878 return sal_False; 879 } 880 881 // ----------------------------------------------------------------------------- 882 883 void SdrExchangeView::YankMarked(sal_uIntPtr /*nFormat*/) 884 { 885 DBG_ERROR( "YankMarked: Not supported anymore" ); 886 } 887 888 // ----------------------------------------------------------------------------- 889 890 sal_Bool SdrExchangeView::Paste(Window* /*pWin*/, sal_uIntPtr /*nFormat*/) 891 { 892 DBG_ERROR( "SdrExchangeView::Paste: Not supported anymore" ); 893 return sal_False; 894 } 895