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