diff options
Diffstat (limited to 'sd/source/ui/app/sdxfer.cxx')
-rw-r--r-- | sd/source/ui/app/sdxfer.cxx | 820 |
1 files changed, 820 insertions, 0 deletions
diff --git a/sd/source/ui/app/sdxfer.cxx b/sd/source/ui/app/sdxfer.cxx new file mode 100644 index 000000000..9ce97f817 --- /dev/null +++ b/sd/source/ui/app/sdxfer.cxx @@ -0,0 +1,820 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <com/sun/star/embed/XEmbeddedObject.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/embed/XEmbedPersist.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <comphelper/fileformat.h> +#include <unotools/ucbstreamhelper.hxx> +#include <unotools/tempfile.hxx> +#include <editeng/flditem.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdotext.hxx> +#include <editeng/outlobj.hxx> +#include <sot/storage.hxx> +#include <editeng/editobj.hxx> +#include <svx/fmglob.hxx> +#include <svx/svdouno.hxx> +#include <svx/ImageMapInfo.hxx> +#include <sot/formats.hxx> +#include <svl/urlbmk.hxx> + +#include <com/sun/star/form/FormButtonType.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <unotools/streamwrap.hxx> + +#include <svx/svdotable.hxx> +#include <svx/unomodel.hxx> +#include <svx/svditer.hxx> +#include <sfx2/docfile.hxx> +#include <comphelper/storagehelper.hxx> +#include <comphelper/servicehelper.hxx> +#include <svtools/embedtransfer.hxx> +#include <DrawDocShell.hxx> +#include <View.hxx> +#include <sdmod.hxx> +#include <sdpage.hxx> +#include <drawdoc.hxx> +#include <stlpool.hxx> +#include <sdxfer.hxx> +#include <unomodel.hxx> +#include <vcl/virdev.hxx> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::clipboard; + +constexpr sal_uInt32 SDTRANSFER_OBJECTTYPE_DRAWMODEL = 1; +constexpr sal_uInt32 SDTRANSFER_OBJECTTYPE_DRAWOLE = 2; + +SdTransferable::SdTransferable( SdDrawDocument* pSrcDoc, ::sd::View* pWorkView, bool bInitOnGetData ) +: mpPageDocShell( nullptr ) +, mpSdView( pWorkView ) +, mpSdViewIntern( pWorkView ) +, mpSdDrawDocument( nullptr ) +, mpSdDrawDocumentIntern( nullptr ) +, mpSourceDoc( pSrcDoc ) +, mpVDev( nullptr ) +, mbInternalMove( false ) +, mbOwnDocument( false ) +, mbOwnView( false ) +, mbLateInit( bInitOnGetData ) +, mbPageTransferable( false ) +, mbPageTransferablePersistent( false ) +, maUserData() +{ + if( mpSourceDoc ) + StartListening( *mpSourceDoc ); + + if( pWorkView ) + StartListening( *pWorkView ); + + if( !mbLateInit ) + CreateData(); +} + +SdTransferable::~SdTransferable() +{ + SolarMutexGuard g; + + if( mpSourceDoc ) + EndListening( *mpSourceDoc ); + + if( mpSdView ) + EndListening( *const_cast< sd::View *>( mpSdView) ); + + ObjectReleased(); + + if( mbOwnView ) + delete mpSdViewIntern; + + mpOLEDataHelper.reset(); + + if( maDocShellRef.is() ) + { + SfxObjectShell* pObj = maDocShellRef.get(); + ::sd::DrawDocShell* pDocSh = static_cast< ::sd::DrawDocShell*>(pObj); + pDocSh->DoClose(); + } + + maDocShellRef.clear(); + + if( mbOwnDocument ) + delete mpSdDrawDocumentIntern; + + mpGraphic.reset(); + mpBookmark.reset(); + mpImageMap.reset(); + + mpVDev.disposeAndClear(); + mpObjDesc.reset(); + + //call explicitly at end of dtor to be covered by above SolarMutex + maUserData.clear(); +} + +void SdTransferable::CreateObjectReplacement( SdrObject* pObj ) +{ + if( pObj ) + { + mpOLEDataHelper.reset(); + mpGraphic.reset(); + mpBookmark.reset(); + mpImageMap.reset(); + + if( nullptr!= dynamic_cast< const SdrOle2Obj* >( pObj ) ) + { + try + { + uno::Reference < embed::XEmbeddedObject > xObj = static_cast< SdrOle2Obj* >( pObj )->GetObjRef(); + uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY ); + if( xObj.is() && xPersist.is() && xPersist->hasEntry() ) + { + mpOLEDataHelper.reset( new TransferableDataHelper( new SvEmbedTransferHelper( xObj, static_cast< SdrOle2Obj* >( pObj )->GetGraphic(), static_cast< SdrOle2Obj* >( pObj )->GetAspect() ) ) ); + + // TODO/LATER: the standalone handling of the graphic should not be used any more in future + // The EmbedDataHelper should bring the graphic in future + const Graphic* pObjGr = static_cast< SdrOle2Obj* >( pObj )->GetGraphic(); + if ( pObjGr ) + mpGraphic.reset( new Graphic( *pObjGr ) ); + } + } + catch( uno::Exception& ) + {} + } + else if( dynamic_cast< const SdrGrafObj *>( pObj ) != nullptr && (mpSourceDoc && !SdDrawDocument::GetAnimationInfo( pObj )) ) + { + mpGraphic.reset( new Graphic( static_cast< SdrGrafObj* >( pObj )->GetTransformedGraphic() ) ); + } + else if( pObj->IsUnoObj() && SdrInventor::FmForm == pObj->GetObjInventor() && ( pObj->GetObjIdentifier() == sal_uInt16(OBJ_FM_BUTTON) ) ) + { + SdrUnoObj* pUnoCtrl = static_cast< SdrUnoObj* >( pObj ); + + if (SdrInventor::FmForm == pUnoCtrl->GetObjInventor()) + { + const Reference< css::awt::XControlModel >& xControlModel( pUnoCtrl->GetUnoControlModel() ); + + if( !xControlModel.is() ) + return; + + Reference< css::beans::XPropertySet > xPropSet( xControlModel, UNO_QUERY ); + + if( !xPropSet.is() ) + return; + + css::form::FormButtonType eButtonType; + Any aTmp( xPropSet->getPropertyValue( "ButtonType" ) ); + + if( aTmp >>= eButtonType ) + { + OUString aLabel, aURL; + + xPropSet->getPropertyValue( "Label" ) >>= aLabel; + xPropSet->getPropertyValue( "TargetURL" ) >>= aURL; + + mpBookmark.reset( new INetBookmark( aURL, aLabel ) ); + } + } + } + else if( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr ) + { + const OutlinerParaObject* pPara; + + if( (pPara = static_cast< SdrTextObj* >( pObj )->GetOutlinerParaObject()) != nullptr ) + { + const SvxFieldItem* pField; + + if( (pField = pPara->GetTextObject().GetField()) != nullptr ) + { + const SvxFieldData* pData = pField->GetField(); + + if( auto pURL = dynamic_cast< const SvxURLField *>( pData ) ) + { + // #i63399# This special code identifies TextFrames which have just a URL + // as content and directly add this to the clipboard, probably to avoid adding + // an unnecessary DrawObject to the target where paste may take place. This is + // wanted only for SdrObjects with no fill and no line, else it is necessary to + // use the whole SdrObect. Test here for Line/FillStyle and take shortcut only + // when both are unused + if(!pObj->HasFillStyle() && !pObj->HasLineStyle()) + { + mpBookmark.reset( new INetBookmark( pURL->GetURL(), pURL->GetRepresentation() ) ); + } + } + } + } + } + + SvxIMapInfo* pInfo = SvxIMapInfo::GetIMapInfo( pObj ); + + if( pInfo ) + mpImageMap.reset( new ImageMap( pInfo->GetImageMap() ) ); + } +} + +void SdTransferable::CreateData() +{ + if( mpSdDrawDocument && !mpSdViewIntern ) + { + mbOwnView = true; + + SdPage* pPage = mpSdDrawDocument->GetSdPage(0, PageKind::Standard); + + if( pPage && 1 == pPage->GetObjCount() ) + CreateObjectReplacement( pPage->GetObj( 0 ) ); + + mpVDev = VclPtr<VirtualDevice>::Create( *Application::GetDefaultDevice() ); + mpVDev->SetMapMode( MapMode( mpSdDrawDocumentIntern->GetScaleUnit(), Point(), mpSdDrawDocumentIntern->GetScaleFraction(), mpSdDrawDocumentIntern->GetScaleFraction() ) ); + mpSdViewIntern = new ::sd::View( *mpSdDrawDocumentIntern, mpVDev ); + mpSdViewIntern->EndListening(*mpSdDrawDocumentIntern ); + mpSdViewIntern->hideMarkHandles(); + SdrPageView* pPageView = mpSdViewIntern->ShowSdrPage(pPage); + mpSdViewIntern->MarkAllObj(pPageView); + } + else if( mpSdView && !mpSdDrawDocumentIntern ) + { + const SdrMarkList& rMarkList = mpSdView->GetMarkedObjectList(); + + if( rMarkList.GetMarkCount() == 1 ) + CreateObjectReplacement( rMarkList.GetMark( 0 )->GetMarkedSdrObj() ); + + if( mpSourceDoc ) + mpSourceDoc->CreatingDataObj(this); + mpSdDrawDocumentIntern = static_cast<SdDrawDocument*>( mpSdView->CreateMarkedObjModel().release() ); + if( mpSourceDoc ) + mpSourceDoc->CreatingDataObj(nullptr); + + if( !maDocShellRef.is() && mpSdDrawDocumentIntern->GetDocSh() ) + maDocShellRef = mpSdDrawDocumentIntern->GetDocSh(); + + if( !maDocShellRef.is() ) + { + OSL_FAIL( "SdTransferable::CreateData(), failed to create a model with persist, clipboard operation will fail for OLE objects!" ); + mbOwnDocument = true; + } + + // Use dimension of source page + SdrPageView* pPgView = mpSdView->GetSdrPageView(); + SdPage* pOldPage = static_cast<SdPage*>( pPgView->GetPage() ); + SdrModel* pOldModel = mpSdView->GetModel(); + SdStyleSheetPool* pOldStylePool = static_cast<SdStyleSheetPool*>( pOldModel->GetStyleSheetPool() ); + SdStyleSheetPool* pNewStylePool = static_cast<SdStyleSheetPool*>( mpSdDrawDocumentIntern->GetStyleSheetPool() ); + SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PageKind::Standard ); + OUString aOldLayoutName( pOldPage->GetLayoutName() ); + + pPage->SetSize( pOldPage->GetSize() ); + pPage->SetLayoutName( aOldLayoutName ); + pNewStylePool->CopyGraphicSheets( *pOldStylePool ); + pNewStylePool->CopyCellSheets( *pOldStylePool ); + pNewStylePool->CopyTableStyles( *pOldStylePool ); + sal_Int32 nPos = aOldLayoutName.indexOf( SD_LT_SEPARATOR ); + if( nPos != -1 ) + aOldLayoutName = aOldLayoutName.copy( 0, nPos ); + StyleSheetCopyResultVector aCreatedSheets; + pNewStylePool->CopyLayoutSheets( aOldLayoutName, *pOldStylePool, aCreatedSheets ); + } + + // set VisArea and adjust objects if necessary + if( maVisArea.IsEmpty() && + mpSdDrawDocumentIntern && mpSdViewIntern && + mpSdDrawDocumentIntern->GetPageCount() ) + { + SdPage* pPage = mpSdDrawDocumentIntern->GetSdPage( 0, PageKind::Standard ); + + if( 1 == mpSdDrawDocumentIntern->GetPageCount() ) + { + // #112978# need to use GetAllMarkedBoundRect instead of GetAllMarkedRect to get + // fat lines correctly + maVisArea = mpSdViewIntern->GetAllMarkedBoundRect(); + Point aOrigin( maVisArea.TopLeft() ); + Size aVector( -aOrigin.X(), -aOrigin.Y() ); + + for( size_t nObj = 0, nObjCount = pPage->GetObjCount(); nObj < nObjCount; ++nObj ) + { + SdrObject* pObj = pPage->GetObj( nObj ); + pObj->NbcMove( aVector ); + } + } + else + maVisArea.SetSize( pPage->GetSize() ); + + // output is at the zero point + maVisArea.SetPos( Point() ); + } +} + +static bool lcl_HasOnlyControls( SdrModel* pModel ) +{ + bool bOnlyControls = false; // default if there are no objects + + if ( pModel ) + { + SdrPage* pPage = pModel->GetPage(0); + if (pPage) + { + SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups ); + SdrObject* pObj = aIter.Next(); + if ( pObj ) + { + bOnlyControls = true; // only set if there are any objects at all + while ( pObj ) + { + if (dynamic_cast< const SdrUnoObj *>( pObj ) == nullptr) + { + bOnlyControls = false; + break; + } + pObj = aIter.Next(); + } + } + } + } + + return bOnlyControls; +} + +static bool lcl_HasOnlyOneTable( SdrModel* pModel ) +{ + if ( pModel ) + { + SdrPage* pPage = pModel->GetPage(0); + if (pPage && pPage->GetObjCount() == 1 ) + { + if( dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) ) != nullptr ) + return true; + } + } + return false; +} + +void SdTransferable::AddSupportedFormats() +{ + if( !mbPageTransferable || mbPageTransferablePersistent ) + { + if( !mbLateInit ) + CreateData(); + + if( mpObjDesc ) + AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ); + + if( mpOLEDataHelper ) + { + AddFormat( SotClipboardFormatId::EMBED_SOURCE ); + + DataFlavorExVector aVector( mpOLEDataHelper->GetDataFlavorExVector() ); + + for( const auto& rItem : aVector ) + AddFormat( rItem ); + } + else if( mpGraphic ) + { + // #i25616# + AddFormat( SotClipboardFormatId::DRAWING ); + + AddFormat( SotClipboardFormatId::SVXB ); + + if( mpGraphic->GetType() == GraphicType::Bitmap ) + { + AddFormat( SotClipboardFormatId::PNG ); + AddFormat( SotClipboardFormatId::BITMAP ); + AddFormat( SotClipboardFormatId::GDIMETAFILE ); + } + else + { + AddFormat( SotClipboardFormatId::GDIMETAFILE ); + AddFormat( SotClipboardFormatId::PNG ); + AddFormat( SotClipboardFormatId::BITMAP ); + } + } + else if( mpBookmark ) + { + AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ); + AddFormat( SotClipboardFormatId::STRING ); + } + else + { + AddFormat( SotClipboardFormatId::EMBED_SOURCE ); + AddFormat( SotClipboardFormatId::DRAWING ); + if( !mpSdDrawDocument || !lcl_HasOnlyControls( mpSdDrawDocument ) ) + { + AddFormat( SotClipboardFormatId::GDIMETAFILE ); + AddFormat( SotClipboardFormatId::PNG ); + AddFormat( SotClipboardFormatId::BITMAP ); + } + + if( lcl_HasOnlyOneTable( mpSdDrawDocument ) ) { + AddFormat( SotClipboardFormatId::RTF ); + AddFormat( SotClipboardFormatId::RICHTEXT ); + } + } + + if( mpImageMap ) + AddFormat( SotClipboardFormatId::SVIM ); + } +} + +bool SdTransferable::GetData( const DataFlavor& rFlavor, const OUString& rDestDoc ) +{ + if (SD_MOD()==nullptr) + return false; + + SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor ); + bool bOK = false; + + CreateData(); + + if( nFormat == SotClipboardFormatId::RTF && lcl_HasOnlyOneTable( mpSdDrawDocument ) ) + { + bOK = SetTableRTF( mpSdDrawDocument ); + } + else if( mpOLEDataHelper && mpOLEDataHelper->HasFormat( rFlavor ) ) + { + // TODO/LATER: support all the graphical formats, the embedded object scenario should not have separated handling + if( nFormat == SotClipboardFormatId::GDIMETAFILE && mpGraphic ) + bOK = SetGDIMetaFile( mpGraphic->GetGDIMetaFile() ); + else + bOK = SetAny( mpOLEDataHelper->GetAny(rFlavor, rDestDoc) ); + } + else if( HasFormat( nFormat ) ) + { + if( ( nFormat == SotClipboardFormatId::LINKSRCDESCRIPTOR || nFormat == SotClipboardFormatId::OBJECTDESCRIPTOR ) && mpObjDesc ) + { + bOK = SetTransferableObjectDescriptor( *mpObjDesc ); + } + else if( nFormat == SotClipboardFormatId::DRAWING ) + { + SfxObjectShellRef aOldRef( maDocShellRef ); + + maDocShellRef.clear(); + + if( mpSdViewIntern ) + { + SdDrawDocument& rInternDoc = mpSdViewIntern->GetDoc(); + rInternDoc.CreatingDataObj(this); + SdDrawDocument* pDoc = dynamic_cast< SdDrawDocument* >( mpSdViewIntern->CreateMarkedObjModel().release() ); + rInternDoc.CreatingDataObj(nullptr); + + bOK = SetObject( pDoc, SDTRANSFER_OBJECTTYPE_DRAWMODEL, rFlavor ); + + if( maDocShellRef.is() ) + { + maDocShellRef->DoClose(); + } + else + { + delete pDoc; + } + } + + maDocShellRef = aOldRef; + } + else if( nFormat == SotClipboardFormatId::GDIMETAFILE ) + { + if (mpSdViewIntern) + { + const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell(); + if (bToggleOnlineSpell) + mpSdDrawDocumentIntern->SetOnlineSpell(false); + bOK = SetGDIMetaFile( mpSdViewIntern->GetMarkedObjMetaFile( true ) ); + if (bToggleOnlineSpell) + mpSdDrawDocumentIntern->SetOnlineSpell(true); + } + } + else if( SotClipboardFormatId::BITMAP == nFormat || SotClipboardFormatId::PNG == nFormat ) + { + if (mpSdViewIntern) + { + const bool bToggleOnlineSpell = mpSdDrawDocumentIntern && mpSdDrawDocumentIntern->GetOnlineSpell(); + if (bToggleOnlineSpell) + mpSdDrawDocumentIntern->SetOnlineSpell(false); + bOK = SetBitmapEx( mpSdViewIntern->GetMarkedObjBitmapEx(true), rFlavor ); + if (bToggleOnlineSpell) + mpSdDrawDocumentIntern->SetOnlineSpell(true); + } + } + else if( ( nFormat == SotClipboardFormatId::STRING ) && mpBookmark ) + { + bOK = SetString( mpBookmark->GetURL(), rFlavor ); + } + else if( ( nFormat == SotClipboardFormatId::SVXB ) && mpGraphic ) + { + bOK = SetGraphic( *mpGraphic ); + } + else if( ( nFormat == SotClipboardFormatId::SVIM ) && mpImageMap ) + { + bOK = SetImageMap( *mpImageMap ); + } + else if( mpBookmark ) + { + bOK = SetINetBookmark( *mpBookmark, rFlavor ); + } + else if( nFormat == SotClipboardFormatId::EMBED_SOURCE ) + { + if( mpSdDrawDocumentIntern ) + { + if( !maDocShellRef.is() ) + { + maDocShellRef = new ::sd::DrawDocShell( + mpSdDrawDocumentIntern, + SfxObjectCreateMode::EMBEDDED, + true, + mpSdDrawDocumentIntern->GetDocumentType()); + mbOwnDocument = false; + maDocShellRef->DoInitNew(); + } + + maDocShellRef->SetVisArea( maVisArea ); + bOK = SetObject( maDocShellRef.get(), SDTRANSFER_OBJECTTYPE_DRAWOLE, rFlavor ); + } + } + } + + return bOK; +} + +bool SdTransferable::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pObject, sal_uInt32 nObjectType, const DataFlavor& ) +{ + bool bRet = false; + + switch( nObjectType ) + { + case SDTRANSFER_OBJECTTYPE_DRAWMODEL: + { + try + { + static const bool bDontBurnInStyleSheet = ( getenv( "AVOID_BURN_IN_FOR_GALLERY_THEME" ) != nullptr ); + SdDrawDocument* pDoc = static_cast<SdDrawDocument*>(pObject); + if ( !bDontBurnInStyleSheet ) + pDoc->BurnInStyleSheetAttributes(); + rxOStm->SetBufferSize( 16348 ); + + Reference< XComponent > xComponent( new SdXImpressDocument( pDoc, true ) ); + pDoc->setUnoModel( Reference< XInterface >::query( xComponent ) ); + + { + css::uno::Reference<css::io::XOutputStream> xDocOut( new utl::OOutputStreamWrapper( *rxOStm ) ); + if( SvxDrawingLayerExport( pDoc, xDocOut, xComponent, (pDoc->GetDocumentType() == DocumentType::Impress) ? "com.sun.star.comp.Impress.XMLClipboardExporter" : "com.sun.star.comp.DrawingLayer.XMLExporter" ) ) + rxOStm->Commit(); + } + + xComponent->dispose(); + bRet = ( rxOStm->GetError() == ERRCODE_NONE ); + } + catch( Exception& ) + { + OSL_FAIL( "sd::SdTransferable::WriteObject(), exception caught!" ); + bRet = false; + } + } + break; + + case SDTRANSFER_OBJECTTYPE_DRAWOLE: + { + SfxObjectShell* pEmbObj = static_cast<SfxObjectShell*>(pObject); + ::utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + + try + { + uno::Reference< embed::XStorage > xWorkStore = + ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE ); + + // write document storage + pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false ); + // mba: no relative URLs for clipboard! + SfxMedium aMedium( xWorkStore, OUString() ); + pEmbObj->DoSaveObjectAs( aMedium, false ); + pEmbObj->DoSaveCompleted(); + + uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY ); + if ( xTransact.is() ) + xTransact->commit(); + + std::unique_ptr<SvStream> pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), StreamMode::READ ); + if( pSrcStm ) + { + rxOStm->SetBufferSize( 0xff00 ); + rxOStm->WriteStream( *pSrcStm ); + pSrcStm.reset(); + } + + bRet = true; + rxOStm->Commit(); + } + catch ( Exception& ) + {} + } + + break; + + default: + break; + } + + return bRet; +} + +void SdTransferable::DragFinished( sal_Int8 nDropAction ) +{ + if( mpSdView ) + const_cast< ::sd::View* >(mpSdView)->DragFinished( nDropAction ); +} + +void SdTransferable::ObjectReleased() +{ + if( this == SD_MOD()->pTransferClip ) + SD_MOD()->pTransferClip = nullptr; + + if( this == SD_MOD()->pTransferDrag ) + SD_MOD()->pTransferDrag = nullptr; + + if( this == SD_MOD()->pTransferSelection ) + SD_MOD()->pTransferSelection = nullptr; +} + +void SdTransferable::SetObjectDescriptor( std::unique_ptr<TransferableObjectDescriptor> pObjDesc ) +{ + mpObjDesc = std::move(pObjDesc); + PrepareOLE( *mpObjDesc ); +} + +void SdTransferable::SetPageBookmarks( const std::vector<OUString> &rPageBookmarks, bool bPersistent ) +{ + if( mpSourceDoc ) + { + if( mpSdViewIntern ) + mpSdViewIntern->HideSdrPage(); + + mpSdDrawDocument->ClearModel(false); + + mpPageDocShell = nullptr; + + maPageBookmarks.clear(); + + if( bPersistent ) + { + mpSdDrawDocument->CreateFirstPages(mpSourceDoc); + mpSdDrawDocument->InsertBookmarkAsPage( rPageBookmarks, nullptr, false, true, 1, true, + mpSourceDoc->GetDocSh(), true, true, false ); + } + else + { + mpPageDocShell = mpSourceDoc->GetDocSh(); + maPageBookmarks = rPageBookmarks; + } + + if( mpSdViewIntern ) + { + SdPage* pPage = mpSdDrawDocument->GetSdPage( 0, PageKind::Standard ); + + if( pPage ) + { + mpSdViewIntern->MarkAllObj( mpSdViewIntern->ShowSdrPage( pPage ) ); + } + } + + // set flags for page transferable; if ( mbPageTransferablePersistent == sal_False ), + // don't offer any formats => it's just for internal purposes + mbPageTransferable = true; + mbPageTransferablePersistent = bPersistent; + } +} + +sal_Int64 SAL_CALL SdTransferable::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) +{ + sal_Int64 nRet; + + if( isUnoTunnelId<SdTransferable>(rId) ) + { + nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); + } + else + { + nRet = 0; + } + + return nRet; +} + +void SdTransferable::AddUserData (const std::shared_ptr<UserData>& rpData) +{ + maUserData.push_back(rpData); +} + +sal_Int32 SdTransferable::GetUserDataCount() const +{ + return maUserData.size(); +} + +std::shared_ptr<SdTransferable::UserData> SdTransferable::GetUserData (const sal_Int32 nIndex) const +{ + if (nIndex>=0 && nIndex<sal_Int32(maUserData.size())) + return maUserData[nIndex]; + else + return std::shared_ptr<UserData>(); +} + +namespace +{ + class theSdTransferableUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSdTransferableUnoTunnelId > {}; +} + +const css::uno::Sequence< sal_Int8 >& SdTransferable::getUnoTunnelId() +{ + return theSdTransferableUnoTunnelId::get().getSeq(); +} + +SdTransferable* SdTransferable::getImplementation( const Reference< XInterface >& rxData ) throw() +{ + try + { + Reference< css::lang::XUnoTunnel > xUnoTunnel( rxData, UNO_QUERY_THROW ); + return reinterpret_cast<SdTransferable*>(sal::static_int_cast<sal_uIntPtr>(xUnoTunnel->getSomething( SdTransferable::getUnoTunnelId()) ) ); + } + catch( const css::uno::Exception& ) + { + } + return nullptr; +} + +void SdTransferable::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint) + { + const SdrHint* pSdrHint = static_cast< const SdrHint* >( &rHint ); + if( SdrHintKind::ModelCleared == pSdrHint->GetKind() ) + { + EndListening(*mpSourceDoc); + mpSourceDoc = nullptr; + } + } + else + { + if( rHint.GetId() == SfxHintId::Dying ) + { + if( &rBC == mpSourceDoc ) + mpSourceDoc = nullptr; + if( &rBC == mpSdViewIntern ) + mpSdViewIntern = nullptr; + if( &rBC == mpSdView ) + mpSdView = nullptr; + } + } +} + +void SdTransferable::SetView(const ::sd::View* pView) +{ + if (mpSdView) + EndListening(*const_cast<sd::View*>(mpSdView)); + mpSdView = pView; + if (mpSdView) + StartListening(*const_cast<sd::View*>(mpSdView)); +} + +bool SdTransferable::SetTableRTF( SdDrawDocument* pModel ) +{ + if ( pModel ) + { + SdrPage* pPage = pModel->GetPage(0); + if (pPage && pPage->GetObjCount() == 1 ) + { + sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( pPage->GetObj(0) ); + if( pTableObj ) + { + SvMemoryStream aMemStm( 65535, 65535 ); + sdr::table::ExportAsRTF( aMemStm, *pTableObj ); + return SetAny( Any( Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.TellEnd() ) ) ); + } + } + } + + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |