1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: embedtransfer.cxx,v $
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
,
58 , m_pGraphic( pGraphic
? new Graphic( *pGraphic
) : NULL
)
59 , m_nAspect( nAspect
)
63 TransferableObjectDescriptor aObjDesc
;
65 FillTransferableObjectDescriptor( aObjDesc
, m_xObj
, NULL
, m_nAspect
);
66 PrepareOLE( aObjDesc
);
70 // -----------------------------------------------------------------------------
72 SvEmbedTransferHelper::~SvEmbedTransferHelper()
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
;
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
116 aTmp
.EnableKillingFile( TRUE
);
117 uno::Reference
< embed::XEmbedPersist
> xPers( m_xObj
, uno::UNO_QUERY
);
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
;
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
);
148 if( ( bRet
= ( aSeq
.getLength() > 0 ) ) == sal_True
)
151 SetAny( aAny
, rFlavor
);
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
);
171 aAny
<<= uno::Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aMemStm
.GetData() ),
172 aMemStm
.Seek( STREAM_SEEK_TO_END
) );
173 SetAny( aAny
, rFlavor
);
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
);
188 catch( uno::Exception
& )
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
,
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
));
225 MapMode
aMapMode( MAP_100TH_MM
);
226 if ( nAspect
== embed::Aspects::MSOLE_ICON
)
230 aMapMode
= pGraphic
->GetPrefMapMode();
231 aSize
= pGraphic
->GetPrefSize();
234 aSize
= Size( 2500, 2500 );
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
;