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