Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sd / source / ui / app / sdxfer.cxx
blob5db900b412bfe1e742195df7ab631aa58412f389
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/embed/ElementModes.hpp>
23 #include <com/sun/star/lang/XComponent.hpp>
24 #include <comphelper/fileformat.h>
25 #include <unotools/ucbstreamhelper.hxx>
26 #include <unotools/tempfile.hxx>
27 #include <editeng/eeitem.hxx>
28 #include <editeng/flditem.hxx>
29 #include <svx/svdpagv.hxx>
30 #include <sfx2/app.hxx>
31 #include <svx/svdoole2.hxx>
32 #include <svx/svdograf.hxx>
33 #include <svx/svdotext.hxx>
34 #include <editeng/outlobj.hxx>
35 #include <sot/storage.hxx>
36 #include <svl/itempool.hxx>
37 #include <editeng/editobj.hxx>
38 #include <svx/fmglob.hxx>
39 #include <svx/svdouno.hxx>
40 #include <sot/formats.hxx>
41 #include <svl/urlbmk.hxx>
42 #include <editeng/outliner.hxx>
44 #include <com/sun/star/form/FormButtonType.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <unotools/streamwrap.hxx>
48 #include <svx/svdotable.hxx>
49 #include <svx/unomodel.hxx>
50 #include <svx/svditer.hxx>
51 #include <sfx2/docfile.hxx>
52 #include <comphelper/storagehelper.hxx>
53 #include <comphelper/servicehelper.hxx>
54 #include <svtools/embedtransfer.hxx>
55 #include <DrawDocShell.hxx>
56 #include <View.hxx>
57 #include <sdpage.hxx>
58 #include <drawview.hxx>
59 #include <drawdoc.hxx>
60 #include <stlpool.hxx>
61 #include <imapinfo.hxx>
62 #include <sdxfer.hxx>
63 #include <unomodel.hxx>
64 #include <vcl/virdev.hxx>
66 using namespace ::com::sun::star;
67 using namespace ::com::sun::star::lang;
68 using namespace ::com::sun::star::uno;
69 using namespace ::com::sun::star::io;
70 using namespace ::com::sun::star::datatransfer;
71 using namespace ::com::sun::star::datatransfer::clipboard;
73 constexpr sal_uInt32 SDTRANSFER_OBJECTTYPE_DRAWMODEL = 1;
74 constexpr sal_uInt32 SDTRANSFER_OBJECTTYPE_DRAWOLE = 2;
76 SdTransferable::SdTransferable( SdDrawDocument* pSrcDoc, ::sd::View* pWorkView, bool bInitOnGetData )
77 : mpPageDocShell( nullptr )
78 , mpOLEDataHelper( nullptr )
79 , mpObjDesc( nullptr )
80 , mpSdView( pWorkView )
81 , mpSdViewIntern( pWorkView )
82 , mpSdDrawDocument( nullptr )
83 , mpSdDrawDocumentIntern( nullptr )
84 , mpSourceDoc( pSrcDoc )
85 , mpVDev( nullptr )
86 , mpBookmark( nullptr )
87 , mpGraphic( nullptr )
88 , mpImageMap( nullptr )
89 , mbInternalMove( false )
90 , mbOwnDocument( false )
91 , mbOwnView( false )
92 , mbLateInit( bInitOnGetData )
93 , mbPageTransferable( false )
94 , mbPageTransferablePersistent( false )
95 , maUserData()
97 if( mpSourceDoc )
98 StartListening( *mpSourceDoc );
100 if( pWorkView )
101 StartListening( *pWorkView );
103 if( !mbLateInit )
104 CreateData();
107 SdTransferable::~SdTransferable()
109 SolarMutexGuard g;
111 if( mpSourceDoc )
112 EndListening( *mpSourceDoc );
114 if( mpSdView )
115 EndListening( *const_cast< sd::View *>( mpSdView) );
117 ObjectReleased();
119 if( mbOwnView )
120 delete mpSdViewIntern;
122 mpOLEDataHelper.reset();
124 if( maDocShellRef.is() )
126 SfxObjectShell* pObj = maDocShellRef.get();
127 ::sd::DrawDocShell* pDocSh = static_cast< ::sd::DrawDocShell*>(pObj);
128 pDocSh->DoClose();
131 maDocShellRef.clear();
133 if( mbOwnDocument )
134 delete mpSdDrawDocumentIntern;
136 mpGraphic.reset();
137 mpBookmark.reset();
138 mpImageMap.reset();
140 mpVDev.disposeAndClear();
141 mpObjDesc.reset();
143 //call explicitly at end of dtor to be covered by above SolarMutex
144 maUserData.clear();
147 void SdTransferable::CreateObjectReplacement( SdrObject* pObj )
149 if( pObj )
151 mpOLEDataHelper.reset();
152 mpGraphic.reset();
153 mpBookmark.reset();
154 mpImageMap.reset();
156 if( nullptr!= dynamic_cast< const SdrOle2Obj* >( pObj ) )
160 uno::Reference < embed::XEmbeddedObject > xObj = static_cast< SdrOle2Obj* >( pObj )->GetObjRef();
161 uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
162 if( xObj.is() && xPersist.is() && xPersist->hasEntry() )
164 mpOLEDataHelper.reset( new TransferableDataHelper( new SvEmbedTransferHelper( xObj, static_cast< SdrOle2Obj* >( pObj )->GetGraphic(), static_cast< SdrOle2Obj* >( pObj )->GetAspect() ) ) );
166 // TODO/LATER: the standalone handling of the graphic should not be used any more in future
167 // The EmbedDataHelper should bring the graphic in future
168 const Graphic* pObjGr = static_cast< SdrOle2Obj* >( pObj )->GetGraphic();
169 if ( pObjGr )
170 mpGraphic.reset( new Graphic( *pObjGr ) );
173 catch( uno::Exception& )
176 else if( dynamic_cast< const SdrGrafObj *>( pObj ) != nullptr && (mpSourceDoc && !SdDrawDocument::GetAnimationInfo( pObj )) )
178 mpGraphic.reset( new Graphic( static_cast< SdrGrafObj* >( pObj )->GetTransformedGraphic() ) );
180 else if( pObj->IsUnoObj() && SdrInventor::FmForm == pObj->GetObjInventor() && ( pObj->GetObjIdentifier() == sal_uInt16(OBJ_FM_BUTTON) ) )
182 SdrUnoObj* pUnoCtrl = static_cast< SdrUnoObj* >( pObj );
184 if (pUnoCtrl && SdrInventor::FmForm == pUnoCtrl->GetObjInventor())
186 Reference< css::awt::XControlModel > xControlModel( pUnoCtrl->GetUnoControlModel() );
188 if( !xControlModel.is() )
189 return;
191 Reference< css::beans::XPropertySet > xPropSet( xControlModel, UNO_QUERY );
193 if( !xPropSet.is() )
194 return;
196 css::form::FormButtonType eButtonType;
197 Any aTmp( xPropSet->getPropertyValue( "ButtonType" ) );
199 if( aTmp >>= eButtonType )
201 OUString aLabel, aURL;
203 xPropSet->getPropertyValue( "Label" ) >>= aLabel;
204 xPropSet->getPropertyValue( "TargetURL" ) >>= aURL;
206 mpBookmark.reset( new INetBookmark( aURL, aLabel ) );
210 else if( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr )
212 const OutlinerParaObject* pPara;
214 if( (pPara = static_cast< SdrTextObj* >( pObj )->GetOutlinerParaObject()) != nullptr )
216 const SvxFieldItem* pField;
218 if( (pField = pPara->GetTextObject().GetField()) != nullptr )
220 const SvxFieldData* pData = pField->GetField();
222 if( pData && dynamic_cast< const SvxURLField *>( pData ) != nullptr )
224 const SvxURLField* pURL = static_cast<const SvxURLField*>(pData);
226 // #i63399# This special code identifies TextFrames which have just an URL
227 // as content and directly add this to the clipboard, probably to avoid adding
228 // an unnecessary DrawObject to the target where paste may take place. This is
229 // wanted only for SdrObjects with no fill and no line, else it is necessary to
230 // use the whole SdrObect. Test here for Line/FillStyle and take shortcut only
231 // when both are unused
232 if(!pObj->HasFillStyle() && !pObj->HasLineStyle())
234 mpBookmark.reset( new INetBookmark( pURL->GetURL(), pURL->GetRepresentation() ) );
241 SdIMapInfo* pInfo = SdDrawDocument::GetIMapInfo( pObj );
243 if( pInfo )
244 mpImageMap.reset( new ImageMap( pInfo->GetImageMap() ) );
248 void SdTransferable::CreateData()
250 if( mpSdDrawDocument && !mpSdViewIntern )
252 mbOwnView = true;
254 SdPage* pPage = mpSdDrawDocument->GetSdPage(0, PageKind::Standard);
256 if( 1 == pPage->GetObjCount() )
257 CreateObjectReplacement( pPage->GetObj( 0 ) );
259 mpVDev = VclPtr<VirtualDevice>::Create( *Application::GetDefaultDevice() );
260 mpVDev->SetMapMode( MapMode( mpSdDrawDocumentIntern->GetScaleUnit(), Point(), mpSdDrawDocumentIntern->GetScaleFraction(), mpSdDrawDocumentIntern->GetScaleFraction() ) );
261 mpSdViewIntern = new ::sd::View( *mpSdDrawDocumentIntern, mpVDev );
262 mpSdViewIntern->EndListening(*mpSdDrawDocumentIntern );
263 mpSdViewIntern->hideMarkHandles();
264 SdrPageView* pPageView = mpSdViewIntern->ShowSdrPage(pPage);
265 mpSdViewIntern->MarkAllObj(pPageView);
267 else if( mpSdView && !mpSdDrawDocumentIntern )
269 const SdrMarkList& rMarkList = mpSdView->GetMarkedObjectList();
271 if( rMarkList.GetMarkCount() == 1 )
272 CreateObjectReplacement( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
274 if( mpSourceDoc )
275 mpSourceDoc->CreatingDataObj(this);
276 mpSdDrawDocumentIntern = static_cast<SdDrawDocument*>( mpSdView->GetMarkedObjModel() );
277 if( mpSourceDoc )
278 mpSourceDoc->CreatingDataObj(nullptr);
280 if( !maDocShellRef.is() && mpSdDrawDocumentIntern->GetDocSh() )
281 maDocShellRef = mpSdDrawDocumentIntern->GetDocSh();
283 if( !maDocShellRef.is() )
285 OSL_FAIL( "SdTransferable::CreateData(), failed to create a model with persist, clipboard operation will fail for OLE objects!" );
286 mbOwnDocument = true;
289 // Use dimension of source page
290 SdrPageView* pPgView = mpSdView->GetSdrPageView();
291 SdPage* pOldPage = static_cast<SdPage*>( pPgView->GetPage() );
292 SdrModel* pOldModel = mpSdView->GetModel();
293 SdStyleSheetPool* pOldStylePool = static_cast<SdStyleSheetPool*>( pOldModel->GetStyleSheetPool() );
294 SdStyleSheetPool* pNewStylePool = static_cast<SdStyleSheetPool*>( mpSdDrawDocumentIntern->GetStyleSheetPool() );
295 SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PageKind::Standard );
296 OUString aOldLayoutName( pOldPage->GetLayoutName() );
298 pPage->SetSize( pOldPage->GetSize() );
299 pPage->SetLayoutName( aOldLayoutName );
300 pNewStylePool->CopyGraphicSheets( *pOldStylePool );
301 pNewStylePool->CopyCellSheets( *pOldStylePool );
302 pNewStylePool->CopyTableStyles( *pOldStylePool );
303 sal_Int32 nPos = aOldLayoutName.indexOf( SD_LT_SEPARATOR );
304 if( nPos != -1 )
305 aOldLayoutName = aOldLayoutName.copy( 0, nPos );
306 SdStyleSheetVector aCreatedSheets;
307 pNewStylePool->CopyLayoutSheets( aOldLayoutName, *pOldStylePool, aCreatedSheets );
310 // set VisArea and adjust objects if necessary
311 if( maVisArea.IsEmpty() &&
312 mpSdDrawDocumentIntern && mpSdViewIntern &&
313 mpSdDrawDocumentIntern->GetPageCount() )
315 SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PageKind::Standard );
317 if( 1 == mpSdDrawDocumentIntern->GetPageCount() )
319 // #112978# need to use GetAllMarkedBoundRect instead of GetAllMarkedRect to get
320 // fat lines correctly
321 Point aOrigin( ( maVisArea = mpSdViewIntern->GetAllMarkedBoundRect() ).TopLeft() );
322 Size aVector( -aOrigin.X(), -aOrigin.Y() );
324 for( size_t nObj = 0, nObjCount = pPage->GetObjCount(); nObj < nObjCount; ++nObj )
326 SdrObject* pObj = pPage->GetObj( nObj );
327 pObj->NbcMove( aVector );
330 else
331 maVisArea.SetSize( pPage->GetSize() );
333 // output is at the zero point
334 maVisArea.SetPos( Point() );
338 static bool lcl_HasOnlyControls( SdrModel* pModel )
340 bool bOnlyControls = false; // default if there are no objects
342 if ( pModel )
344 SdrPage* pPage = pModel->GetPage(0);
345 if (pPage)
347 SdrObjListIter aIter( *pPage, SdrIterMode::DeepNoGroups );
348 SdrObject* pObj = aIter.Next();
349 if ( pObj )
351 bOnlyControls = true; // only set if there are any objects at all
352 while ( pObj )
354 if (dynamic_cast< const SdrUnoObj *>( pObj ) == nullptr)
356 bOnlyControls = false;
357 break;
359 pObj = aIter.Next();
365 return bOnlyControls;
368 static bool lcl_HasOnlyOneTable( SdrModel* pModel )
370 if ( pModel )
372 SdrPage* pPage = pModel->GetPage(0);
373 if (pPage && pPage->GetObjCount() == 1 )
375 if( dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) ) != nullptr )
376 return true;
379 return false;
382 void SdTransferable::AddSupportedFormats()
384 if( !mbPageTransferable || mbPageTransferablePersistent )
386 if( !mbLateInit )
387 CreateData();
389 if( mpObjDesc )
390 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
392 if( mpOLEDataHelper )
394 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
396 DataFlavorExVector aVector( mpOLEDataHelper->GetDataFlavorExVector() );
397 DataFlavorExVector::iterator aIter( aVector.begin() ), aEnd( aVector.end() );
399 while( aIter != aEnd )
400 AddFormat( *aIter++ );
402 else if( mpGraphic )
404 // #i25616#
405 AddFormat( SotClipboardFormatId::DRAWING );
407 AddFormat( SotClipboardFormatId::SVXB );
409 if( mpGraphic->GetType() == GraphicType::Bitmap )
411 AddFormat( SotClipboardFormatId::PNG );
412 AddFormat( SotClipboardFormatId::BITMAP );
413 AddFormat( SotClipboardFormatId::GDIMETAFILE );
415 else
417 AddFormat( SotClipboardFormatId::GDIMETAFILE );
418 AddFormat( SotClipboardFormatId::PNG );
419 AddFormat( SotClipboardFormatId::BITMAP );
422 else if( mpBookmark )
424 AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK );
425 AddFormat( SotClipboardFormatId::STRING );
427 else
429 AddFormat( SotClipboardFormatId::EMBED_SOURCE );
430 AddFormat( SotClipboardFormatId::DRAWING );
431 if( !mpSdDrawDocument || !lcl_HasOnlyControls( mpSdDrawDocument ) )
433 AddFormat( SotClipboardFormatId::GDIMETAFILE );
434 AddFormat( SotClipboardFormatId::PNG );
435 AddFormat( SotClipboardFormatId::BITMAP );
438 if( lcl_HasOnlyOneTable( mpSdDrawDocument ) ) {
439 AddFormat( SotClipboardFormatId::RTF );
440 AddFormat( SotClipboardFormatId::RICHTEXT );
444 if( mpImageMap )
445 AddFormat( SotClipboardFormatId::SVIM );
449 bool SdTransferable::GetData( const DataFlavor& rFlavor, const OUString& rDestDoc )
451 if (SD_MOD()==nullptr)
452 return false;
454 SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
455 bool bOK = false;
457 CreateData();
459 if( nFormat == SotClipboardFormatId::RTF && lcl_HasOnlyOneTable( mpSdDrawDocument ) )
461 bOK = SetTableRTF( mpSdDrawDocument );
463 else if( mpOLEDataHelper && mpOLEDataHelper->HasFormat( rFlavor ) )
465 SdrSwapGraphicsMode nOldSwapMode(SdrSwapGraphicsMode::DEFAULT);
467 if( mpSdDrawDocumentIntern )
469 nOldSwapMode = mpSdDrawDocumentIntern->GetSwapGraphicsMode();
470 mpSdDrawDocumentIntern->SetSwapGraphicsMode( SdrSwapGraphicsMode::PURGE );
473 // TODO/LATER: support all the graphical formats, the embedded object scenario should not have separated handling
474 if( nFormat == SotClipboardFormatId::GDIMETAFILE && mpGraphic )
475 bOK = SetGDIMetaFile( mpGraphic->GetGDIMetaFile() );
476 else
477 bOK = SetAny( mpOLEDataHelper->GetAny(rFlavor, rDestDoc) );
479 if( mpSdDrawDocumentIntern )
480 mpSdDrawDocumentIntern->SetSwapGraphicsMode( nOldSwapMode );
482 else if( HasFormat( nFormat ) )
484 if( ( nFormat == SotClipboardFormatId::LINKSRCDESCRIPTOR || nFormat == SotClipboardFormatId::OBJECTDESCRIPTOR ) && mpObjDesc )
486 bOK = SetTransferableObjectDescriptor( *mpObjDesc );
488 else if( nFormat == SotClipboardFormatId::DRAWING )
490 SfxObjectShellRef aOldRef( maDocShellRef );
492 maDocShellRef.clear();
494 if( mpSdViewIntern )
496 SdDrawDocument& rInternDoc = mpSdViewIntern->GetDoc();
497 rInternDoc.CreatingDataObj(this);
498 SdDrawDocument* pDoc = dynamic_cast< SdDrawDocument* >( mpSdViewIntern->GetMarkedObjModel() );
499 rInternDoc.CreatingDataObj(nullptr);
501 bOK = SetObject( pDoc, SDTRANSFER_OBJECTTYPE_DRAWMODEL, rFlavor );
503 if( maDocShellRef.is() )
505 maDocShellRef->DoClose();
507 else
509 delete pDoc;
513 maDocShellRef = aOldRef;
515 else if( nFormat == SotClipboardFormatId::GDIMETAFILE )
517 if (mpSdViewIntern)
519 const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell();
520 if (bToggleOnlineSpell)
521 mpSdDrawDocumentIntern->SetOnlineSpell(false);
522 bOK = SetGDIMetaFile( mpSdViewIntern->GetMarkedObjMetaFile( true ) );
523 if (bToggleOnlineSpell)
524 mpSdDrawDocumentIntern->SetOnlineSpell(true);
527 else if( SotClipboardFormatId::BITMAP == nFormat || SotClipboardFormatId::PNG == nFormat )
529 if (mpSdViewIntern)
531 const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell();
532 if (bToggleOnlineSpell)
533 mpSdDrawDocumentIntern->SetOnlineSpell(false);
534 bOK = SetBitmapEx( mpSdViewIntern->GetMarkedObjBitmapEx(true), rFlavor );
535 if (bToggleOnlineSpell)
536 mpSdDrawDocumentIntern->SetOnlineSpell(true);
539 else if( ( nFormat == SotClipboardFormatId::STRING ) && mpBookmark )
541 bOK = SetString( mpBookmark->GetURL(), rFlavor );
543 else if( ( nFormat == SotClipboardFormatId::SVXB ) && mpGraphic )
545 bOK = SetGraphic( *mpGraphic );
547 else if( ( nFormat == SotClipboardFormatId::SVIM ) && mpImageMap )
549 bOK = SetImageMap( *mpImageMap );
551 else if( mpBookmark )
553 bOK = SetINetBookmark( *mpBookmark, rFlavor );
555 else if( nFormat == SotClipboardFormatId::EMBED_SOURCE )
557 if( mpSdDrawDocumentIntern )
559 SdrSwapGraphicsMode nOldSwapMode = mpSdDrawDocumentIntern->GetSwapGraphicsMode();
560 mpSdDrawDocumentIntern->SetSwapGraphicsMode( SdrSwapGraphicsMode::PURGE );
562 if( !maDocShellRef.is() )
564 maDocShellRef = new ::sd::DrawDocShell(
565 mpSdDrawDocumentIntern,
566 SfxObjectCreateMode::EMBEDDED,
567 true,
568 mpSdDrawDocumentIntern->GetDocumentType());
569 mbOwnDocument = false;
570 maDocShellRef->DoInitNew();
573 maDocShellRef->SetVisArea( maVisArea );
574 bOK = SetObject( maDocShellRef.get(), SDTRANSFER_OBJECTTYPE_DRAWOLE, rFlavor );
576 mpSdDrawDocumentIntern->SetSwapGraphicsMode( nOldSwapMode );
581 return bOK;
584 bool SdTransferable::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pObject, sal_uInt32 nObjectType, const DataFlavor& )
586 bool bRet = false;
588 switch( nObjectType )
590 case SDTRANSFER_OBJECTTYPE_DRAWMODEL:
594 static const bool bDontBurnInStyleSheet = ( getenv( "AVOID_BURN_IN_FOR_GALLERY_THEME" ) != nullptr );
595 SdDrawDocument* pDoc = static_cast<SdDrawDocument*>(pObject);
596 if ( !bDontBurnInStyleSheet )
597 pDoc->BurnInStyleSheetAttributes();
598 rxOStm->SetBufferSize( 16348 );
600 Reference< XComponent > xComponent( new SdXImpressDocument( pDoc, true ) );
601 pDoc->setUnoModel( Reference< XInterface >::query( xComponent ) );
604 css::uno::Reference<css::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) );
605 if( SvxDrawingLayerExport( pDoc, xDocOut, xComponent, (pDoc->GetDocumentType() == DocumentType::Impress) ? "com.sun.star.comp.Impress.XMLClipboardExporter" : "com.sun.star.comp.DrawingLayer.XMLExporter" ) )
606 rxOStm->Commit();
609 xComponent->dispose();
610 bRet = ( rxOStm->GetError() == ERRCODE_NONE );
612 catch( Exception& )
614 OSL_FAIL( "sd::SdTransferable::WriteObject(), exception caught!" );
615 bRet = false;
618 break;
620 case SDTRANSFER_OBJECTTYPE_DRAWOLE:
622 SfxObjectShell* pEmbObj = static_cast<SfxObjectShell*>(pObject);
623 ::utl::TempFile aTempFile;
624 aTempFile.EnableKillingFile();
628 uno::Reference< embed::XStorage > xWorkStore =
629 ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
631 // write document storage
632 pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false );
633 // mba: no relative URLs for clipboard!
634 SfxMedium aMedium( xWorkStore, OUString() );
635 bRet = pEmbObj->DoSaveObjectAs( aMedium, false );
636 pEmbObj->DoSaveCompleted();
638 uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
639 if ( xTransact.is() )
640 xTransact->commit();
642 SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), StreamMode::READ );
643 if( pSrcStm )
645 rxOStm->SetBufferSize( 0xff00 );
646 rxOStm->WriteStream( *pSrcStm );
647 delete pSrcStm;
650 bRet = true;
651 rxOStm->Commit();
653 catch ( Exception& )
657 break;
659 default:
660 break;
663 return bRet;
666 void SdTransferable::DragFinished( sal_Int8 nDropAction )
668 if( mpSdView )
669 const_cast< ::sd::View* >(mpSdView)->DragFinished( nDropAction );
672 void SdTransferable::ObjectReleased()
674 if( this == SD_MOD()->pTransferClip )
675 SD_MOD()->pTransferClip = nullptr;
677 if( this == SD_MOD()->pTransferDrag )
678 SD_MOD()->pTransferDrag = nullptr;
680 if( this == SD_MOD()->pTransferSelection )
681 SD_MOD()->pTransferSelection = nullptr;
684 void SdTransferable::SetObjectDescriptor( std::unique_ptr<TransferableObjectDescriptor> pObjDesc )
686 mpObjDesc = std::move(pObjDesc);
687 PrepareOLE( *mpObjDesc );
690 void SdTransferable::SetPageBookmarks( const std::vector<OUString> &rPageBookmarks, bool bPersistent )
692 if( mpSourceDoc )
694 if( mpSdViewIntern )
695 mpSdViewIntern->HideSdrPage();
697 mpSdDrawDocument->ClearModel(false);
699 mpPageDocShell = nullptr;
701 maPageBookmarks.clear();
703 if( bPersistent )
705 mpSdDrawDocument->CreateFirstPages(mpSourceDoc);
706 mpSdDrawDocument->InsertBookmarkAsPage( rPageBookmarks, nullptr, false, true, 1, true,
707 mpSourceDoc->GetDocSh(), true, true, false );
709 else
711 mpPageDocShell = mpSourceDoc->GetDocSh();
712 maPageBookmarks = rPageBookmarks;
715 if( mpSdViewIntern )
717 SdPage* pPage = mpSdDrawDocument->GetSdPage( 0, PageKind::Standard );
719 if( pPage )
721 mpSdViewIntern->MarkAllObj( mpSdViewIntern->ShowSdrPage( pPage ) );
725 // set flags for page transferable; if ( mbPageTransferablePersistent == sal_False ),
726 // don't offer any formats => it's just for internal purposes
727 mbPageTransferable = true;
728 mbPageTransferablePersistent = bPersistent;
732 sal_Int64 SAL_CALL SdTransferable::getSomething( const css::uno::Sequence< sal_Int8 >& rId )
734 sal_Int64 nRet;
736 if( ( rId.getLength() == 16 ) &&
737 ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
739 nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
741 else
743 nRet = 0;
746 return nRet;
749 void SdTransferable::AddUserData (const std::shared_ptr<UserData>& rpData)
751 maUserData.push_back(rpData);
754 sal_Int32 SdTransferable::GetUserDataCount() const
756 return maUserData.size();
759 std::shared_ptr<SdTransferable::UserData> SdTransferable::GetUserData (const sal_Int32 nIndex) const
761 if (nIndex>=0 && nIndex<sal_Int32(maUserData.size()))
762 return maUserData[nIndex];
763 else
764 return std::shared_ptr<UserData>();
767 namespace
769 class theSdTransferableUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSdTransferableUnoTunnelId > {};
772 const css::uno::Sequence< sal_Int8 >& SdTransferable::getUnoTunnelId()
774 return theSdTransferableUnoTunnelId::get().getSeq();
777 SdTransferable* SdTransferable::getImplementation( const Reference< XInterface >& rxData ) throw()
781 Reference< css::lang::XUnoTunnel > xUnoTunnel( rxData, UNO_QUERY_THROW );
782 return reinterpret_cast<SdTransferable*>(sal::static_int_cast<sal_uIntPtr>(xUnoTunnel->getSomething( SdTransferable::getUnoTunnelId()) ) );
784 catch( const css::uno::Exception& )
787 return nullptr;
790 void SdTransferable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
792 const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint );
793 if( pSdrHint )
795 if( SdrHintKind::ModelCleared == pSdrHint->GetKind() )
797 EndListening(*mpSourceDoc);
798 mpSourceDoc = nullptr;
801 else
803 if( rHint.GetId() == SfxHintId::Dying )
805 if( &rBC == mpSourceDoc )
806 mpSourceDoc = nullptr;
807 if( &rBC == mpSdViewIntern )
808 mpSdViewIntern = nullptr;
809 if( &rBC == mpSdView )
810 mpSdView = nullptr;
815 void SdTransferable::SetView(const ::sd::View* pView)
817 if (mpSdView)
818 EndListening(*const_cast<sd::View*>(mpSdView));
819 mpSdView = pView;
820 if (mpSdView)
821 StartListening(*const_cast<sd::View*>(mpSdView));
824 bool SdTransferable::SetTableRTF( SdDrawDocument* pModel )
826 if ( pModel )
828 SdrPage* pPage = pModel->GetPage(0);
829 if (pPage && pPage->GetObjCount() == 1 )
831 sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) );
832 if( pTableObj )
834 SvMemoryStream aMemStm( 65535, 65535 );
835 sdr::table::SdrTableObj::ExportAsRTF( aMemStm, *pTableObj );
836 return SetAny( Any( Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ) ) );
841 return false;
844 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */