Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / app / drwtrans.cxx
blobd228d9f85072d78d2ef981ed69dd83e7430566ec
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/embed/XTransactedObject.hpp>
21 #include <com/sun/star/embed/XEmbedPersist.hpp>
22 #include <com/sun/star/uno/Exception.hpp>
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <com/sun/star/beans/XPropertySetInfo.hpp>
26 #include <com/sun/star/form/FormButtonType.hpp>
27 #include <toolkit/helper/vclunohelper.hxx>
28 #include <unotools/streamwrap.hxx>
30 #include <svx/unomodel.hxx>
31 #include <unotools/tempfile.hxx>
32 #include <unotools/ucbstreamhelper.hxx>
33 #include <comphelper/storagehelper.hxx>
34 #include <comphelper/servicehelper.hxx>
36 #include <svtools/embedtransfer.hxx>
37 #include <sot/storage.hxx>
38 #include <vcl/virdev.hxx>
39 #include <svx/fmglob.hxx>
40 #include <svx/svditer.hxx>
41 #include <svx/svdograf.hxx>
42 #include <svx/svdoole2.hxx>
43 #include <svx/svdouno.hxx>
44 #include <svx/svdpage.hxx>
45 #include <svx/svdxcgv.hxx>
46 #include <sfx2/docfile.hxx>
47 #include <svl/itempool.hxx>
48 #include <svl/urlbmk.hxx>
49 #include <tools/urlobj.hxx>
50 #include <osl/mutex.hxx>
52 #include "drwtrans.hxx"
53 #include "docsh.hxx"
54 #include "drwlayer.hxx"
55 #include "drawview.hxx"
56 #include "viewdata.hxx"
57 #include "scmod.hxx"
58 #include "chartlis.hxx"
59 #include "rangeutl.hxx"
60 #include <formula/grammar.hxx>
61 #include "dragdata.hxx"
62 #include "clipdata.hxx"
64 #include "scitems.hxx"
66 #include <editeng/eeitem.hxx>
68 #include <editeng/fhgtitem.hxx>
69 #include <vcl/svapp.hxx>
71 using namespace com::sun::star;
73 #define SCDRAWTRANS_TYPE_EMBOBJ SotClipboardFormatId::STRING
74 #define SCDRAWTRANS_TYPE_DRAWMODEL SotClipboardFormatId::BITMAP
75 #define SCDRAWTRANS_TYPE_DOCUMENT SotClipboardFormatId::GDIMETAFILE
77 ScDrawTransferObj::ScDrawTransferObj( SdrModel* pClipModel, ScDocShell* pContainerShell,
78 const TransferableObjectDescriptor& rDesc ) :
79 pModel( pClipModel ),
80 aObjDesc( rDesc ),
81 pBookmark( nullptr ),
82 bGraphic( false ),
83 bGrIsBit( false ),
84 bOleObj( false ),
85 pDragSourceView( nullptr ),
86 nDragSourceFlags( 0 ),
87 bDragWasInternal( false ),
88 nSourceDocID( 0 ),
89 maShellID(SfxObjectShell::CreateShellID(pContainerShell))
92 // check what kind of objects are contained
94 SdrPage* pPage = pModel->GetPage(0);
95 if (pPage)
97 SdrObjListIter aIter( *pPage, IM_FLAT );
98 SdrObject* pObject = aIter.Next();
99 if (pObject && !aIter.Next()) // exactly one object?
102 // OLE object
104 sal_uInt16 nSdrObjKind = pObject->GetObjIdentifier();
105 if (nSdrObjKind == OBJ_OLE2)
107 // if object has no persistence it must be copied as a part of document
110 uno::Reference< embed::XEmbedPersist > xPersObj( static_cast<SdrOle2Obj*>(pObject)->GetObjRef(), uno::UNO_QUERY );
111 if ( xPersObj.is() && xPersObj->hasEntry() )
112 bOleObj = true;
114 catch( uno::Exception& )
116 // aOleData is initialized later
119 // Graphic object
121 if (nSdrObjKind == OBJ_GRAF)
123 bGraphic = true;
124 if ( static_cast<SdrGrafObj*>(pObject)->GetGraphic().GetType() == GRAPHIC_BITMAP )
125 bGrIsBit = true;
128 // URL button
130 SdrUnoObj* pUnoCtrl = dynamic_cast<SdrUnoObj*>( pObject );
131 if (pUnoCtrl && FmFormInventor == pUnoCtrl->GetObjInventor())
133 uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel();
134 OSL_ENSURE( xControlModel.is(), "uno control without model" );
135 if ( xControlModel.is() )
137 uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
138 uno::Reference< beans::XPropertySetInfo > xInfo = xPropSet->getPropertySetInfo();
140 OUString sPropButtonType( "ButtonType" );
141 OUString sPropTargetURL( "TargetURL" );
142 OUString sPropLabel( "Label" );
144 if(xInfo->hasPropertyByName( sPropButtonType ))
146 uno::Any aAny = xPropSet->getPropertyValue( sPropButtonType );
147 form::FormButtonType eTmp;
148 if ( (aAny >>= eTmp) && eTmp == form::FormButtonType_URL )
150 // URL
151 if(xInfo->hasPropertyByName( sPropTargetURL ))
153 aAny = xPropSet->getPropertyValue( sPropTargetURL );
154 OUString sTmp;
155 if ( (aAny >>= sTmp) && !sTmp.isEmpty() )
157 OUString aUrl = sTmp;
158 OUString aAbs;
159 const SfxMedium* pMedium;
160 if (pContainerShell && (pMedium = pContainerShell->GetMedium()) != nullptr)
162 bool bWasAbs = true;
163 aAbs = pMedium->GetURLObject().smartRel2Abs( aUrl, bWasAbs ).
164 GetMainURL(INetURLObject::NO_DECODE);
165 // full path as stored INetBookmark must be encoded
167 else
168 aAbs = aUrl;
170 // Label
171 OUString aLabel;
172 if(xInfo->hasPropertyByName( sPropLabel ))
174 aAny = xPropSet->getPropertyValue( sPropLabel );
175 if ( (aAny >>= sTmp) && !sTmp.isEmpty() )
177 aLabel = sTmp;
180 pBookmark = new INetBookmark( aAbs, aLabel );
190 // get size for object descriptor
192 // #i71538# use complete SdrViews
193 // SdrExchangeView aView(pModel);
194 SdrView aView(pModel);
195 SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
196 aView.MarkAllObj(pPv);
197 aSrcSize = aView.GetAllMarkedRect().GetSize();
199 if ( bOleObj ) // single OLE object
201 SdrOle2Obj* pObj = GetSingleObject();
202 if ( pObj && pObj->GetObjRef().is() )
203 SvEmbedTransferHelper::FillTransferableObjectDescriptor( aObjDesc, pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect() );
206 aObjDesc.maSize = aSrcSize;
207 PrepareOLE( aObjDesc );
209 // remember a unique ID of the source document
211 if ( pContainerShell )
213 ScDocument& rDoc = pContainerShell->GetDocument();
214 nSourceDocID = rDoc.GetDocumentID();
215 if ( pPage )
217 ScChartHelper::FillProtectedChartRangesVector( m_aProtectedChartRangesVector, &rDoc, pPage );
222 ScDrawTransferObj::~ScDrawTransferObj()
224 SolarMutexGuard aSolarGuard;
226 ScModule* pScMod = SC_MOD();
227 if ( pScMod->GetClipData().pDrawClipboard == this )
229 OSL_FAIL("ScDrawTransferObj wasn't released");
230 pScMod->SetClipObject( nullptr, nullptr );
232 if ( pScMod->GetDragData().pDrawTransfer == this )
234 OSL_FAIL("ScDrawTransferObj wasn't released");
235 pScMod->ResetDragObject();
238 aOleData = TransferableDataHelper(); // clear before releasing the mutex
239 aDocShellRef.Clear();
241 delete pModel;
242 aDrawPersistRef.Clear(); // after the model
244 delete pBookmark;
245 delete pDragSourceView;
248 ScDrawTransferObj* ScDrawTransferObj::GetOwnClipboard( vcl::Window* )
250 ScDrawTransferObj* pObj = SC_MOD()->GetClipData().pDrawClipboard;
251 return pObj;
254 static bool lcl_HasOnlyControls( SdrModel* pModel )
256 bool bOnlyControls = false; // default if there are no objects
258 if ( pModel )
260 SdrPage* pPage = pModel->GetPage(0);
261 if (pPage)
263 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
264 SdrObject* pObj = aIter.Next();
265 if ( pObj )
267 bOnlyControls = true; // only set if there are any objects at all
268 while ( pObj )
270 if (dynamic_cast<const SdrUnoObj*>( pObj) == nullptr)
272 bOnlyControls = false;
273 break;
275 pObj = aIter.Next();
281 return bOnlyControls;
284 void ScDrawTransferObj::AddSupportedFormats()
286 if ( bGrIsBit ) // single bitmap graphic
288 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
289 AddFormat( SotClipboardFormatId::SVXB );
290 AddFormat( SotClipboardFormatId::PNG );
291 AddFormat( SotClipboardFormatId::BITMAP );
292 AddFormat( SotClipboardFormatId::GDIMETAFILE );
294 else if ( bGraphic ) // other graphic
296 // #i25616#
297 AddFormat( SotClipboardFormatId::DRAWING );
299 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
300 AddFormat( SotClipboardFormatId::SVXB );
301 AddFormat( SotClipboardFormatId::GDIMETAFILE );
302 AddFormat( SotClipboardFormatId::PNG );
303 AddFormat( SotClipboardFormatId::BITMAP );
305 else if ( pBookmark ) // url button
307 // AddFormat( SotClipboardFormatId::EMBED_SOURCE );
308 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
309 AddFormat( SotClipboardFormatId::SOLK );
310 AddFormat( SotClipboardFormatId::STRING );
311 AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR );
312 AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
313 AddFormat( SotClipboardFormatId::DRAWING );
315 else if ( bOleObj ) // single OLE object
317 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
318 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
319 AddFormat( SotClipboardFormatId::GDIMETAFILE );
321 CreateOLEData();
323 if ( aOleData.GetTransferable().is() )
325 // get format list from object snapshot
326 // (this must be after inserting the default formats!)
328 DataFlavorExVector aVector( aOleData.GetDataFlavorExVector() );
329 DataFlavorExVector::iterator aIter( aVector.begin() ), aEnd( aVector.end() );
331 while( aIter != aEnd )
332 AddFormat( *aIter++ );
335 else // any drawing objects
337 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
338 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
339 AddFormat( SotClipboardFormatId::DRAWING );
341 // leave out bitmap and metafile if there are only controls
342 if ( !lcl_HasOnlyControls( pModel ) )
344 AddFormat( SotClipboardFormatId::PNG );
345 AddFormat( SotClipboardFormatId::BITMAP );
346 AddFormat( SotClipboardFormatId::GDIMETAFILE );
350 // if( pImageMap )
351 // AddFormat( SotClipboardFormatId::SVIM );
354 bool ScDrawTransferObj::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc )
356 bool bOK = false;
357 SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
359 if ( bOleObj && nFormat != SotClipboardFormatId::GDIMETAFILE )
361 CreateOLEData();
363 if( aOleData.GetTransferable().is() && aOleData.HasFormat( rFlavor ) )
365 SdrSwapGraphicsMode nOldSwapMode(SdrSwapGraphicsMode::DEFAULT);
367 if( pModel )
369 nOldSwapMode = pModel->GetSwapGraphicsMode();
370 pModel->SetSwapGraphicsMode( SdrSwapGraphicsMode::PURGE );
373 bOK = SetAny( aOleData.GetAny(rFlavor, rDestDoc), rFlavor );
375 if( pModel )
376 pModel->SetSwapGraphicsMode( nOldSwapMode );
378 return bOK;
382 if( HasFormat( nFormat ) )
384 if ( nFormat == SotClipboardFormatId::LINKSRCDESCRIPTOR || nFormat == SotClipboardFormatId::OBJECTDESCRIPTOR )
386 bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor );
388 else if ( nFormat == SotClipboardFormatId::DRAWING )
390 bOK = SetObject( pModel, SCDRAWTRANS_TYPE_DRAWMODEL, rFlavor );
392 else if ( nFormat == SotClipboardFormatId::BITMAP
393 || nFormat == SotClipboardFormatId::PNG
394 || nFormat == SotClipboardFormatId::GDIMETAFILE )
396 // #i71538# use complete SdrViews
397 // SdrExchangeView aView( pModel );
398 SdrView aView( pModel );
399 SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
400 OSL_ENSURE( pPv, "pPv not there..." );
401 aView.MarkAllObj( pPv );
402 if ( nFormat == SotClipboardFormatId::GDIMETAFILE )
403 bOK = SetGDIMetaFile( aView.GetMarkedObjMetaFile(true), rFlavor );
404 else
405 bOK = SetBitmapEx( aView.GetMarkedObjBitmapEx(true), rFlavor );
407 else if ( nFormat == SotClipboardFormatId::SVXB )
409 // only enabled for single graphics object
411 SdrPage* pPage = pModel->GetPage(0);
412 if (pPage)
414 SdrObjListIter aIter( *pPage, IM_FLAT );
415 SdrObject* pObject = aIter.Next();
416 if (pObject && pObject->GetObjIdentifier() == OBJ_GRAF)
418 SdrGrafObj* pGraphObj = static_cast<SdrGrafObj*>(pObject);
419 bOK = SetGraphic( pGraphObj->GetGraphic(), rFlavor );
423 else if ( nFormat == SotClipboardFormatId::EMBED_SOURCE )
425 if ( bOleObj ) // single OLE object
427 SdrOle2Obj* pObj = GetSingleObject();
428 if ( pObj && pObj->GetObjRef().is() )
430 bOK = SetObject( pObj->GetObjRef().get(), SCDRAWTRANS_TYPE_EMBOBJ, rFlavor );
433 else // create object from contents
435 //TODO/LATER: needs new Format, because now single OLE and "this" are different
436 InitDocShell(); // set aDocShellRef
438 SfxObjectShell* pEmbObj = aDocShellRef;
439 bOK = SetObject( pEmbObj, SCDRAWTRANS_TYPE_DOCUMENT, rFlavor );
442 else if( pBookmark )
444 bOK = SetINetBookmark( *pBookmark, rFlavor );
447 return bOK;
450 bool ScDrawTransferObj::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pUserObject, SotClipboardFormatId nUserObjectId,
451 const css::datatransfer::DataFlavor& /* rFlavor */ )
453 // called from SetObject, put data into stream
455 bool bRet = false;
456 switch (nUserObjectId)
458 case SCDRAWTRANS_TYPE_DRAWMODEL:
460 SdrModel* pDrawModel = static_cast<SdrModel*>(pUserObject);
461 rxOStm->SetBufferSize( 0xff00 );
463 // for the changed pool defaults from drawing layer pool set those
464 // attributes as hard attributes to preserve them for saving
465 const SfxItemPool& rItemPool = pModel->GetItemPool();
466 const SvxFontHeightItem& rDefaultFontHeight = static_cast<const SvxFontHeightItem&>(rItemPool.GetDefaultItem(EE_CHAR_FONTHEIGHT));
468 // SW should have no MasterPages
469 OSL_ENSURE(0 == pModel->GetMasterPageCount(), "SW with MasterPages (!)");
471 for(sal_uInt16 a(0); a < pModel->GetPageCount(); a++)
473 const SdrPage* pPage = pModel->GetPage(a);
474 SdrObjListIter aIter(*pPage, IM_DEEPNOGROUPS);
476 while(aIter.IsMore())
478 SdrObject* pObj = aIter.Next();
479 const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(pObj->GetMergedItem(EE_CHAR_FONTHEIGHT));
481 if(rItem.GetHeight() == rDefaultFontHeight.GetHeight())
483 pObj->SetMergedItem(rDefaultFontHeight);
489 css::uno::Reference<css::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
490 if( SvxDrawingLayerExport( pDrawModel, xDocOut ) )
491 rxOStm->Commit();
494 bRet = ( rxOStm->GetError() == ERRCODE_NONE );
496 break;
498 case SCDRAWTRANS_TYPE_EMBOBJ:
500 // impl. for "single OLE"
501 embed::XEmbeddedObject* pEmbObj = static_cast<embed::XEmbeddedObject*>(pUserObject);
503 ::utl::TempFile aTempFile;
504 aTempFile.EnableKillingFile();
505 uno::Reference< embed::XStorage > xWorkStore =
506 ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
508 uno::Reference < embed::XEmbedPersist > xPers( static_cast<embed::XVisualObject*>(pEmbObj), uno::UNO_QUERY );
509 if ( xPers.is() )
513 uno::Sequence < beans::PropertyValue > aSeq;
514 OUString aDummyName("Dummy");
515 xPers->storeToEntry( xWorkStore, aDummyName, aSeq, aSeq );
516 if ( xWorkStore->isStreamElement( aDummyName ) )
518 uno::Reference < io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
519 uno::Reference < io::XStream > xNewStream = xWorkStore->openStreamElement( aDummyName, embed::ElementModes::READ );
520 ::comphelper::OStorageHelper::CopyInputToOutput( xNewStream->getInputStream(), xDocOut );
522 else
524 uno::Reference < io::XStream > xDocStr( new utl::OStreamWrapper( *rxOStm ) );
525 uno::Reference< embed::XStorage > xDocStg = ::comphelper::OStorageHelper::GetStorageFromStream( xDocStr );
526 uno::Reference < embed::XStorage > xNewStg = xWorkStore->openStorageElement( aDummyName, embed::ElementModes::READ );
527 xNewStg->copyToStorage( xDocStg );
528 uno::Reference < embed::XTransactedObject > xTrans( xDocStg, uno::UNO_QUERY );
529 if ( xTrans.is() )
530 xTrans->commit();
533 rxOStm->Commit();
535 catch ( uno::Exception& )
540 break;
542 case SCDRAWTRANS_TYPE_DOCUMENT:
544 // impl. for "DocShell"
545 SfxObjectShell* pEmbObj = static_cast<SfxObjectShell*>(pUserObject);
549 ::utl::TempFile aTempFile;
550 aTempFile.EnableKillingFile();
551 uno::Reference< embed::XStorage > xWorkStore =
552 ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
554 // write document storage
555 pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
557 // mba: no relative URLs for clipboard!
558 SfxMedium aMedium( xWorkStore, OUString() );
559 pEmbObj->DoSaveObjectAs( aMedium, false );
560 pEmbObj->DoSaveCompleted();
562 uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
563 if ( xTransact.is() )
564 xTransact->commit();
566 SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), StreamMode::READ );
567 if( pSrcStm )
569 rxOStm->SetBufferSize( 0xff00 );
570 rxOStm->WriteStream( *pSrcStm );
571 delete pSrcStm;
574 xWorkStore->dispose();
575 xWorkStore.clear();
576 rxOStm->Commit();
578 catch ( uno::Exception& )
581 bRet = ( rxOStm->GetError() == ERRCODE_NONE );
583 break;
585 default:
586 OSL_FAIL("unknown object id");
588 return bRet;
591 void ScDrawTransferObj::ObjectReleased()
593 ScModule* pScMod = SC_MOD();
594 if ( pScMod->GetClipData().pDrawClipboard == this )
595 pScMod->SetClipObject( nullptr, nullptr );
597 TransferableHelper::ObjectReleased();
600 void ScDrawTransferObj::DragFinished( sal_Int8 nDropAction )
602 if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) )
604 // move: delete source objects
606 if ( pDragSourceView )
607 pDragSourceView->DeleteMarked();
610 ScModule* pScMod = SC_MOD();
611 if ( pScMod->GetDragData().pDrawTransfer == this )
612 pScMod->ResetDragObject();
614 DELETEZ( pDragSourceView );
616 TransferableHelper::DragFinished( nDropAction );
619 void ScDrawTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef )
621 aDrawPersistRef = rRef;
624 static void lcl_InitMarks( SdrMarkView& rDest, const SdrMarkView& rSource, SCTAB nTab )
626 rDest.ShowSdrPage(rDest.GetModel()->GetPage(nTab));
627 SdrPageView* pDestPV = rDest.GetSdrPageView();
628 OSL_ENSURE(pDestPV,"PageView ?");
630 const SdrMarkList& rMarkList = rSource.GetMarkedObjectList();
631 const size_t nCount = rMarkList.GetMarkCount();
632 for (size_t i=0; i<nCount; ++i)
634 SdrMark* pMark = rMarkList.GetMark(i);
635 SdrObject* pObj = pMark->GetMarkedSdrObj();
637 rDest.MarkObj(pObj, pDestPV);
641 void ScDrawTransferObj::SetDragSource( ScDrawView* pView )
643 DELETEZ( pDragSourceView );
644 pDragSourceView = new SdrView( pView->GetModel() );
645 lcl_InitMarks( *pDragSourceView, *pView, pView->GetTab() );
647 //! add as listener with document, delete pDragSourceView if document gone
650 void ScDrawTransferObj::SetDragSourceObj( SdrObject* pObj, SCTAB nTab )
652 DELETEZ( pDragSourceView );
653 pDragSourceView = new SdrView( pObj->GetModel() );
654 pDragSourceView->ShowSdrPage(pDragSourceView->GetModel()->GetPage(nTab));
655 SdrPageView* pPV = pDragSourceView->GetSdrPageView();
656 pDragSourceView->MarkObj(pObj, pPV);
658 //! add as listener with document, delete pDragSourceView if document gone
661 void ScDrawTransferObj::SetDragSourceFlags( sal_uInt16 nFlags )
663 nDragSourceFlags = nFlags;
666 void ScDrawTransferObj::SetDragWasInternal()
668 bDragWasInternal = true;
671 const OUString& ScDrawTransferObj::GetShellID() const
673 return maShellID;
676 SdrOle2Obj* ScDrawTransferObj::GetSingleObject()
678 // if single OLE object was copied, get its object
680 SdrPage* pPage = pModel->GetPage(0);
681 if (pPage)
683 SdrObjListIter aIter( *pPage, IM_FLAT );
684 SdrObject* pObject = aIter.Next();
685 if (pObject && pObject->GetObjIdentifier() == OBJ_OLE2)
687 return static_cast<SdrOle2Obj*>(pObject);
691 return nullptr;
694 void ScDrawTransferObj::CreateOLEData()
696 if (aOleData.GetTransferable().is())
697 // Already created.
698 return;
700 SdrOle2Obj* pObj = GetSingleObject();
701 if (!pObj || !pObj->GetObjRef().is())
702 // No OLE object present.
703 return;
705 SvEmbedTransferHelper* pEmbedTransfer =
706 new SvEmbedTransferHelper(
707 pObj->GetObjRef(), pObj->GetGraphic(), pObj->GetAspect());
709 pEmbedTransfer->SetParentShellID(maShellID);
711 aOleData = TransferableDataHelper(pEmbedTransfer);
714 // initialize aDocShellRef with a live document from the ClipDoc
716 void ScDrawTransferObj::InitDocShell()
718 if ( !aDocShellRef.Is() )
720 ScDocShell* pDocSh = new ScDocShell;
721 aDocShellRef = pDocSh; // ref must be there before InitNew
723 pDocSh->DoInitNew();
725 ScDocument& rDestDoc = pDocSh->GetDocument();
726 rDestDoc.InitDrawLayer( pDocSh );
728 SdrModel* pDestModel = rDestDoc.GetDrawLayer();
729 // #i71538# use complete SdrViews
730 // SdrExchangeView aDestView( pDestModel );
731 SdrView aDestView( pDestModel );
732 aDestView.ShowSdrPage(aDestView.GetModel()->GetPage(0));
733 aDestView.Paste(
734 *pModel,
735 Point(aSrcSize.Width()/2, aSrcSize.Height()/2),
736 nullptr, SdrInsertFlags::NONE);
738 // put objects to right layer (see ScViewFunc::PasteDataFormat for SotClipboardFormatId::DRAWING)
740 SdrPage* pPage = pDestModel->GetPage(0);
741 if (pPage)
743 SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
744 SdrObject* pObject = aIter.Next();
745 while (pObject)
747 if ( dynamic_cast<const SdrUnoObj*>( pObject) != nullptr )
748 pObject->NbcSetLayer(SC_LAYER_CONTROLS);
749 else
750 pObject->NbcSetLayer(SC_LAYER_FRONT);
751 pObject = aIter.Next();
755 Point aTmpPoint;
756 Rectangle aDestArea( aTmpPoint, aSrcSize );
757 pDocSh->SetVisArea( aDestArea );
759 ScViewOptions aViewOpt( rDestDoc.GetViewOptions() );
760 aViewOpt.SetOption( VOPT_GRID, false );
761 rDestDoc.SetViewOptions( aViewOpt );
763 ScViewData aViewData( pDocSh, nullptr );
764 aViewData.SetTabNo( 0 );
765 aViewData.SetScreen( aDestArea );
766 aViewData.SetCurX( 0 );
767 aViewData.SetCurY( 0 );
768 pDocSh->UpdateOle(&aViewData, true);
772 namespace
774 class theScDrawTransferObjUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScDrawTransferObjUnoTunnelId > {};
777 const css::uno::Sequence< sal_Int8 >& ScDrawTransferObj::getUnoTunnelId()
779 return theScDrawTransferObjUnoTunnelId::get().getSeq();
782 sal_Int64 SAL_CALL ScDrawTransferObj::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) throw( css::uno::RuntimeException, std::exception )
784 sal_Int64 nRet;
785 if( ( rId.getLength() == 16 ) &&
786 ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
788 nRet = reinterpret_cast< sal_Int64 >( this );
790 else
791 nRet = TransferableHelper::getSomething(rId);
792 return nRet;
795 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */