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