1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_svtools.hxx" 30*cdf0e10cSrcweir #include <com/sun/star/embed/XComponentSupplier.hpp> 31*cdf0e10cSrcweir #include <com/sun/star/embed/EmbedStates.hpp> 32*cdf0e10cSrcweir #include <com/sun/star/embed/XVisualObject.hpp> 33*cdf0e10cSrcweir #include <com/sun/star/embed/XEmbedPersist.hpp> 34*cdf0e10cSrcweir #include <com/sun/star/embed/NoVisualAreaSizeException.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/datatransfer/XTransferable.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/embed/Aspects.hpp> 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include <svtools/embedtransfer.hxx> 39*cdf0e10cSrcweir #include <tools/mapunit.hxx> 40*cdf0e10cSrcweir #include <vcl/outdev.hxx> 41*cdf0e10cSrcweir #include <comphelper/storagehelper.hxx> 42*cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx> 43*cdf0e10cSrcweir #include <unotools/streamwrap.hxx> 44*cdf0e10cSrcweir #include <unotools/tempfile.hxx> 45*cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx> 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #include <svtools/embedhlp.hxx> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir using namespace ::com::sun::star; 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir SvEmbedTransferHelper::SvEmbedTransferHelper( const uno::Reference< embed::XEmbeddedObject >& xObj, 52*cdf0e10cSrcweir Graphic* pGraphic, 53*cdf0e10cSrcweir sal_Int64 nAspect ) 54*cdf0e10cSrcweir : m_xObj( xObj ) 55*cdf0e10cSrcweir , m_pGraphic( pGraphic ? new Graphic( *pGraphic ) : NULL ) 56*cdf0e10cSrcweir , m_nAspect( nAspect ) 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir if( xObj.is() ) 59*cdf0e10cSrcweir { 60*cdf0e10cSrcweir TransferableObjectDescriptor aObjDesc; 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir FillTransferableObjectDescriptor( aObjDesc, m_xObj, NULL, m_nAspect ); 63*cdf0e10cSrcweir PrepareOLE( aObjDesc ); 64*cdf0e10cSrcweir } 65*cdf0e10cSrcweir } 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir SvEmbedTransferHelper::~SvEmbedTransferHelper() 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir if ( m_pGraphic ) 72*cdf0e10cSrcweir { 73*cdf0e10cSrcweir delete m_pGraphic; 74*cdf0e10cSrcweir m_pGraphic = NULL; 75*cdf0e10cSrcweir } 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir void SvEmbedTransferHelper::AddSupportedFormats() 81*cdf0e10cSrcweir { 82*cdf0e10cSrcweir AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ); 83*cdf0e10cSrcweir AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ); 84*cdf0e10cSrcweir AddFormat( FORMAT_GDIMETAFILE ); 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir sal_Bool SvEmbedTransferHelper::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ) 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir sal_Bool bRet = sal_False; 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir if( m_xObj.is() ) 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir try 96*cdf0e10cSrcweir { 97*cdf0e10cSrcweir sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor ); 98*cdf0e10cSrcweir if( HasFormat( nFormat ) ) 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir if( nFormat == SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir TransferableObjectDescriptor aDesc; 103*cdf0e10cSrcweir FillTransferableObjectDescriptor( aDesc, m_xObj, m_pGraphic, m_nAspect ); 104*cdf0e10cSrcweir bRet = SetTransferableObjectDescriptor( aDesc, rFlavor ); 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir else if( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE ) 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir try 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir // TODO/LATER: Propbably the graphic should be copied here as well 111*cdf0e10cSrcweir // currently it is handled by the applications 112*cdf0e10cSrcweir utl::TempFile aTmp; 113*cdf0e10cSrcweir aTmp.EnableKillingFile( sal_True ); 114*cdf0e10cSrcweir uno::Reference < embed::XEmbedPersist > xPers( m_xObj, uno::UNO_QUERY ); 115*cdf0e10cSrcweir if ( xPers.is() ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir uno::Reference < embed::XStorage > xStg = comphelper::OStorageHelper::GetTemporaryStorage(); 118*cdf0e10cSrcweir ::rtl::OUString aName = ::rtl::OUString::createFromAscii("Dummy"); 119*cdf0e10cSrcweir SvStream* pStream = NULL; 120*cdf0e10cSrcweir sal_Bool bDeleteStream = sal_False; 121*cdf0e10cSrcweir uno::Sequence < beans::PropertyValue > aEmpty; 122*cdf0e10cSrcweir xPers->storeToEntry( xStg, aName, aEmpty, aEmpty ); 123*cdf0e10cSrcweir if ( xStg->isStreamElement( aName ) ) 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir uno::Reference < io::XStream > xStm = xStg->cloneStreamElement( aName ); 126*cdf0e10cSrcweir pStream = utl::UcbStreamHelper::CreateStream( xStm ); 127*cdf0e10cSrcweir bDeleteStream = sal_True; 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir else 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir pStream = aTmp.GetStream( STREAM_STD_READWRITE ); 132*cdf0e10cSrcweir uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetStorageFromStream( new utl::OStreamWrapper( *pStream ) ); 133*cdf0e10cSrcweir xStg->openStorageElement( aName, embed::ElementModes::READ )->copyToStorage( xStor ); 134*cdf0e10cSrcweir } 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir ::com::sun::star::uno::Any aAny; 137*cdf0e10cSrcweir const sal_uInt32 nLen = pStream->Seek( STREAM_SEEK_TO_END ); 138*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( nLen ); 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir pStream->Seek( STREAM_SEEK_TO_BEGIN ); 141*cdf0e10cSrcweir pStream->Read( aSeq.getArray(), nLen ); 142*cdf0e10cSrcweir if ( bDeleteStream ) 143*cdf0e10cSrcweir delete pStream; 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir if( ( bRet = ( aSeq.getLength() > 0 ) ) == sal_True ) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir aAny <<= aSeq; 148*cdf0e10cSrcweir SetAny( aAny, rFlavor ); 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir else 152*cdf0e10cSrcweir { 153*cdf0e10cSrcweir //TODO/LATER: how to handle objects without persistance?! 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir catch ( uno::Exception& ) 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir else if ( nFormat == FORMAT_GDIMETAFILE && m_pGraphic ) 161*cdf0e10cSrcweir { 162*cdf0e10cSrcweir SvMemoryStream aMemStm( 65535, 65535 ); 163*cdf0e10cSrcweir aMemStm.SetVersion( SOFFICE_FILEFORMAT_CURRENT ); 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir const GDIMetaFile& aMetaFile = m_pGraphic->GetGDIMetaFile(); 166*cdf0e10cSrcweir ((GDIMetaFile*)(&aMetaFile))->Write( aMemStm ); 167*cdf0e10cSrcweir uno::Any aAny; 168*cdf0e10cSrcweir aAny <<= uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), 169*cdf0e10cSrcweir aMemStm.Seek( STREAM_SEEK_TO_END ) ); 170*cdf0e10cSrcweir SetAny( aAny, rFlavor ); 171*cdf0e10cSrcweir bRet = sal_True; 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir else if ( m_xObj.is() && :: svt::EmbeddedObjectRef::TryRunningState( m_xObj ) ) 174*cdf0e10cSrcweir { 175*cdf0e10cSrcweir uno::Reference< datatransfer::XTransferable > xTransferable( m_xObj->getComponent(), uno::UNO_QUERY ); 176*cdf0e10cSrcweir if ( xTransferable.is() ) 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir uno::Any aAny = xTransferable->getTransferData( rFlavor ); 179*cdf0e10cSrcweir SetAny( aAny, rFlavor ); 180*cdf0e10cSrcweir bRet = sal_True; 181*cdf0e10cSrcweir } 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir catch( uno::Exception& ) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir // Error handling? 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir return bRet; 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir void SvEmbedTransferHelper::ObjectReleased() 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir m_xObj = uno::Reference< embed::XEmbeddedObject >(); 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir void SvEmbedTransferHelper::FillTransferableObjectDescriptor( TransferableObjectDescriptor& rDesc, 202*cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XEmbeddedObject >& xObj, 203*cdf0e10cSrcweir Graphic* pGraphic, 204*cdf0e10cSrcweir sal_Int64 nAspect ) 205*cdf0e10cSrcweir { 206*cdf0e10cSrcweir //TODO/LATER: need TypeName to fill it into the Descriptor (will be shown in listbox) 207*cdf0e10cSrcweir ::com::sun::star::datatransfer::DataFlavor aFlavor; 208*cdf0e10cSrcweir SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aFlavor ); 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir rDesc.maClassName = SvGlobalName( xObj->getClassID() ); 211*cdf0e10cSrcweir rDesc.maTypeName = aFlavor.HumanPresentableName; 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir //TODO/LATER: the aspect size in the descriptor is wrong, unfortunately the stream 214*cdf0e10cSrcweir // representation of the descriptor allows only 4 bytes for the aspect 215*cdf0e10cSrcweir // so for internal transport something different should be found 216*cdf0e10cSrcweir rDesc.mnViewAspect = sal::static_int_cast<sal_uInt16>( nAspect ); 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir //TODO/LATER: status needs to become sal_Int64 219*cdf0e10cSrcweir rDesc.mnOle2Misc = sal::static_int_cast<sal_Int32>(xObj->getStatus( rDesc.mnViewAspect )); 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir Size aSize; 222*cdf0e10cSrcweir MapMode aMapMode( MAP_100TH_MM ); 223*cdf0e10cSrcweir if ( nAspect == embed::Aspects::MSOLE_ICON ) 224*cdf0e10cSrcweir { 225*cdf0e10cSrcweir if ( pGraphic ) 226*cdf0e10cSrcweir { 227*cdf0e10cSrcweir aMapMode = pGraphic->GetPrefMapMode(); 228*cdf0e10cSrcweir aSize = pGraphic->GetPrefSize(); 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir else 231*cdf0e10cSrcweir aSize = Size( 2500, 2500 ); 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir else 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir try 236*cdf0e10cSrcweir { 237*cdf0e10cSrcweir awt::Size aSz; 238*cdf0e10cSrcweir aSz = xObj->getVisualAreaSize( rDesc.mnViewAspect ); 239*cdf0e10cSrcweir aSize = Size( aSz.Width, aSz.Height ); 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir catch( embed::NoVisualAreaSizeException& ) 242*cdf0e10cSrcweir { 243*cdf0e10cSrcweir OSL_ENSURE( sal_False, "Can not get visual area size!\n" ); 244*cdf0e10cSrcweir aSize = Size( 5000, 5000 ); 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir // TODO/LEAN: getMapUnit can switch object to running state 248*cdf0e10cSrcweir aMapMode = MapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( rDesc.mnViewAspect ) ) ); 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir rDesc.maSize = OutputDevice::LogicToLogic( aSize, aMapMode, MapMode( MAP_100TH_MM ) ); 252*cdf0e10cSrcweir rDesc.maDragStartPos = Point(); 253*cdf0e10cSrcweir rDesc.maDisplayName = String(); 254*cdf0e10cSrcweir rDesc.mbCanLink = sal_False; 255*cdf0e10cSrcweir } 256*cdf0e10cSrcweir 257