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 BitmapEx SdrExchangeView::GetMarkedObjBitmapEx(bool bNoVDevIfOneBmpMarked) const 533 { 534 BitmapEx aBmp; 535 536 if( AreObjectsMarked() ) 537 { 538 if(1 == GetMarkedObjectCount()) 539 { 540 if(bNoVDevIfOneBmpMarked) 541 { 542 SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 ); 543 SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL; 544 545 if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) ) 546 { 547 aBmp = pGrafObj->GetTransformedGraphic().GetBitmapEx(); 548 } 549 } 550 else 551 { 552 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(GetMarkedObjectByIndex(0)); 553 554 if(pSdrGrafObj && pSdrGrafObj->isEmbeddedSvg()) 555 { 556 aBmp = pSdrGrafObj->GetGraphic().getSvgData()->getReplacement(); 557 } 558 } 559 } 560 561 if( !aBmp ) 562 { 563 const Graphic aGraphic(GetMarkedObjMetaFile(bNoVDevIfOneBmpMarked)); 564 565 // #i102089# support user's settings of AA and LineSnap when the MetaFile gets 566 // rasterconverted to a bitmap 567 const SvtOptionsDrawinglayer aDrawinglayerOpt; 568 const GraphicConversionParameters aParameters( 569 Size(), 570 false, 571 aDrawinglayerOpt.IsAntiAliasing(), 572 aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete()); 573 574 aBmp = aGraphic.GetBitmapEx(aParameters); 575 } 576 } 577 578 return aBmp; 579 } 580 581 // ----------------------------------------------------------------------------- 582 583 GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile(bool bNoVDevIfOneMtfMarked) const 584 { 585 GDIMetaFile aMtf; 586 587 if( AreObjectsMarked() ) 588 { 589 Rectangle aBound( GetMarkedObjBoundRect() ); 590 Size aBoundSize( aBound.GetWidth(), aBound.GetHeight() ); 591 MapMode aMap( pMod->GetScaleUnit(), Point(), pMod->GetScaleFraction(), pMod->GetScaleFraction() ); 592 593 if( bNoVDevIfOneMtfMarked ) 594 { 595 SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 ); 596 SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() ==1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL; 597 598 if( pGrafObj ) 599 { 600 Graphic aGraphic( pGrafObj->GetTransformedGraphic() ); 601 602 if( aGraphic.GetType() == GRAPHIC_BITMAP ) 603 { 604 const Point aPos; 605 606 aMtf.AddAction( new MetaBmpExScaleAction( aPos, aBoundSize, aGraphic.GetBitmapEx() ) ); 607 aMtf.SetPrefMapMode( aMap ); 608 aMtf.SetPrefSize( aBoundSize ); 609 } 610 else 611 aMtf = aGraphic.GetGDIMetaFile(); 612 } 613 } 614 615 if( !aMtf.GetActionCount() ) 616 { 617 VirtualDevice aOut; 618 const Size aDummySize(2, 2); 619 620 aOut.SetOutputSizePixel(aDummySize); 621 aOut.EnableOutput(false); 622 aOut.SetMapMode(aMap); 623 aMtf.Clear(); 624 aMtf.Record(&aOut); 625 626 DrawMarkedObj(aOut); 627 628 aMtf.Stop(); 629 aMtf.WindStart(); 630 631 // moving the result is more reliable then setting a relative MapMode at the VDev (used 632 // before), also see #i99268# in GetObjGraphic() below. Some draw actions at 633 // the OutDev are simply not handled correctly when a MapMode is set at the 634 // target devive, e.g. MetaFloatTransparentAction. Even the Move for this action 635 // was missing the manipulation of the embedded Metafile 636 aMtf.Move(-aBound.Left(), -aBound.Top()); 637 638 aMtf.SetPrefMapMode( aMap ); 639 640 // removed PrefSize extension. It is principially wrong to set a reduced size at 641 // the created MetaFile. The mentioned errors occurr at output time since the integer 642 // MapModes from VCL lead to errors. It is now corrected in the VCLRenderer for 643 // primitives (and may later be done in breaking up a MetaFile to primitives) 644 aMtf.SetPrefSize(aBoundSize); 645 } 646 } 647 648 return aMtf; 649 } 650 651 // ----------------------------------------------------------------------------- 652 653 Graphic SdrExchangeView::GetAllMarkedGraphic() const 654 { 655 Graphic aRet; 656 657 if( AreObjectsMarked() ) 658 { 659 if( ( 1 == GetMarkedObjectCount() ) && GetSdrMarkByIndex( 0 ) ) 660 aRet = SdrExchangeView::GetObjGraphic( pMod, GetMarkedObjectByIndex( 0 ) ); 661 else 662 aRet = GetMarkedObjMetaFile(false); 663 } 664 665 return aRet; 666 } 667 668 // ----------------------------------------------------------------------------- 669 670 Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject* pObj ) 671 { 672 Graphic aRet; 673 674 if( pModel && pObj ) 675 { 676 // try to get a graphic from the object first 677 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj); 678 const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj); 679 680 if(pSdrGrafObj) 681 { 682 if(pSdrGrafObj->isEmbeddedSvg()) 683 { 684 // get Metafile for Svg content 685 aRet = pSdrGrafObj->getMetafileFromEmbeddedSvg(); 686 } 687 else 688 { 689 // #110981# Make behaviour coherent with metafile 690 // recording below (which of course also takes 691 // view-transformed objects) 692 aRet = pSdrGrafObj->GetTransformedGraphic(); 693 } 694 } 695 else if(pSdrOle2Obj) 696 { 697 if ( pSdrOle2Obj->GetGraphic() ) 698 aRet = *pSdrOle2Obj->GetGraphic(); 699 } 700 701 // if graphic could not be retrieved => go the hard way and create a MetaFile 702 if( ( GRAPHIC_NONE == aRet.GetType() ) || ( GRAPHIC_DEFAULT == aRet.GetType() ) ) 703 { 704 VirtualDevice aOut; 705 GDIMetaFile aMtf; 706 const Rectangle aBoundRect( pObj->GetCurrentBoundRect() ); 707 const MapMode aMap( pModel->GetScaleUnit(), 708 Point(), 709 pModel->GetScaleFraction(), 710 pModel->GetScaleFraction() ); 711 712 aOut.EnableOutput( sal_False ); 713 aOut.SetMapMode( aMap ); 714 aMtf.Record( &aOut ); 715 pObj->SingleObjectPainter( aOut ); // #110094#-17 716 aMtf.Stop(); 717 aMtf.WindStart(); 718 719 // #i99268# replace the original offset from using XOutDev's SetOffset 720 // NOT (as tried with #i92760#) with another MapMode which gets recorded 721 // by the Metafile itself (what always leads to problems), but by 722 // moving the result directly 723 aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top()); 724 725 aMtf.SetPrefMapMode( aMap ); 726 aMtf.SetPrefSize( aBoundRect.GetSize() ); 727 728 if( aMtf.GetActionCount() ) 729 aRet = aMtf; 730 } 731 } 732 733 return aRet; 734 } 735 736 // ----------------------------------------------------------------------------- 737 738 void SdrExchangeView::DrawMarkedObj(OutputDevice& rOut) const 739 { 740 SortMarkedObjects(); 741 742 ::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 ); 743 ::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ]; 744 ::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ]; 745 const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin(); 746 const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False ); 747 sal_uInt32 n, nCount; 748 749 for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ ) 750 { 751 SdrMark* pMark = GetSdrMarkByIndex( n ); 752 753 // paint objects on control layer on top of all otherobjects 754 if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() ) 755 rObjVector2.push_back( pMark ); 756 else 757 rObjVector1.push_back( pMark ); 758 } 759 760 for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ ) 761 { 762 ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ]; 763 764 for( sal_uInt32 i = 0; i < rObjVector.size(); i++ ) 765 { 766 SdrMark* pMark = rObjVector[ i ]; 767 pMark->GetMarkedSdrObj()->SingleObjectPainter( rOut ); // #110094#-17 768 } 769 } 770 } 771 772 // ----------------------------------------------------------------------------- 773 774 SdrModel* SdrExchangeView::GetMarkedObjModel() const 775 { 776 // Wenn das sortieren der MarkList mal stoeren sollte, 777 // werde ich sie mir wohl kopieren muessen. 778 SortMarkedObjects(); 779 SdrModel* pNeuMod=pMod->AllocModel(); 780 SdrPage* pNeuPag=pNeuMod->AllocPage(sal_False); 781 pNeuMod->InsertPage(pNeuPag); 782 783 if( !mxSelectionController.is() || !mxSelectionController->GetMarkedObjModel( pNeuPag ) ) 784 { 785 ::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 ); 786 ::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ]; 787 ::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ]; 788 const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin(); 789 const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), sal_False ); 790 sal_uInt32 n, nCount, nCloneErrCnt = 0; 791 792 for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ ) 793 { 794 SdrMark* pMark = GetSdrMarkByIndex( n ); 795 796 // paint objects on control layer on top of all otherobjects 797 if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() ) 798 rObjVector2.push_back( pMark ); 799 else 800 rObjVector1.push_back( pMark ); 801 } 802 803 // #i13033# 804 // New mechanism to re-create the connections of cloned connectors 805 CloneList aCloneList; 806 807 for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ ) 808 { 809 ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ]; 810 811 for( sal_uInt32 i = 0; i < rObjVector.size(); i++ ) 812 { 813 const SdrMark* pMark = rObjVector[ i ]; 814 const SdrObject* pObj = pMark->GetMarkedSdrObj(); 815 SdrObject* pNeuObj; 816 817 if( pObj->ISA( SdrPageObj ) ) 818 { 819 // convert SdrPageObj's to a graphic representation, because 820 // virtual connection to referenced page gets lost in new model 821 pNeuObj = new SdrGrafObj( GetObjGraphic( pMod, pObj ), pObj->GetLogicRect() ); 822 pNeuObj->SetPage( pNeuPag ); 823 pNeuObj->SetModel( pNeuMod ); 824 } 825 else 826 { 827 // #116235# 828 // pNeuObj = pObj->Clone( pNeuPag, pNeuMod ); 829 pNeuObj = pObj->Clone(); 830 pNeuObj->SetPage( pNeuPag ); 831 pNeuObj->SetModel( pNeuMod ); 832 } 833 834 if( pNeuObj ) 835 { 836 SdrInsertReason aReason(SDRREASON_VIEWCALL); 837 pNeuPag->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason); 838 839 // #i13033# 840 aCloneList.AddPair(pObj, pNeuObj); 841 } 842 else 843 nCloneErrCnt++; 844 } 845 } 846 847 // #i13033# 848 // New mechanism to re-create the connections of cloned connectors 849 aCloneList.CopyConnections(); 850 851 if(0L != nCloneErrCnt) 852 { 853 #ifdef DBG_UTIL 854 ByteString aStr("SdrExchangeView::GetMarkedObjModel(): Fehler beim Clonen "); 855 856 if(nCloneErrCnt == 1) 857 { 858 aStr += "eines Zeichenobjekts."; 859 } 860 else 861 { 862 aStr += "von "; 863 aStr += ByteString::CreateFromInt32( nCloneErrCnt ); 864 aStr += " Zeichenobjekten."; 865 } 866 867 aStr += " Objektverbindungen werden nicht mitkopiert."; 868 869 DBG_ERROR(aStr.GetBuffer()); 870 #endif 871 } 872 } 873 return pNeuMod; 874 } 875 876 // ----------------------------------------------------------------------------- 877 878 sal_Bool SdrExchangeView::Cut( sal_uIntPtr /*nFormat */) 879 { 880 DBG_ERROR( "SdrExchangeView::Cut: Not supported anymore" ); 881 return sal_False; 882 } 883 884 // ----------------------------------------------------------------------------- 885 886 void SdrExchangeView::CutMarked( sal_uIntPtr /*nFormat */) 887 { 888 DBG_ERROR( "SdrExchangeView::CutMarked: Not supported anymore" ); 889 } 890 891 // ----------------------------------------------------------------------------- 892 893 sal_Bool SdrExchangeView::Yank(sal_uIntPtr /*nFormat*/) 894 { 895 DBG_ERROR( "SdrExchangeView::Yank: Not supported anymore" ); 896 return sal_False; 897 } 898 899 // ----------------------------------------------------------------------------- 900 901 void SdrExchangeView::YankMarked(sal_uIntPtr /*nFormat*/) 902 { 903 DBG_ERROR( "YankMarked: Not supported anymore" ); 904 } 905 906 // ----------------------------------------------------------------------------- 907 908 sal_Bool SdrExchangeView::Paste(Window* /*pWin*/, sal_uIntPtr /*nFormat*/) 909 { 910 DBG_ERROR( "SdrExchangeView::Paste: Not supported anymore" ); 911 return sal_False; 912 } 913