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