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