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