1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/XComponentSupplier.hpp>
21 #include <com/sun/star/embed/EmbedStates.hpp>
22 #include <com/sun/star/embed/XVisualObject.hpp>
23 #include <com/sun/star/embed/XEmbedPersist.hpp>
24 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
25 #include <com/sun/star/datatransfer/XTransferable.hpp>
26 #include <com/sun/star/embed/Aspects.hpp>
28 #include <svtools/embedtransfer.hxx>
29 #include <tools/mapunit.hxx>
30 #include <vcl/outdev.hxx>
31 #include <comphelper/storagehelper.hxx>
32 #include <unotools/ucbstreamhelper.hxx>
33 #include <unotools/streamwrap.hxx>
34 #include <unotools/tempfile.hxx>
35 #include <toolkit/helper/vclunohelper.hxx>
37 #include <svtools/embedhlp.hxx>
39 using namespace ::com::sun::star
;
41 SvEmbedTransferHelper::SvEmbedTransferHelper( const uno::Reference
< embed::XEmbeddedObject
>& xObj
,
42 const Graphic
* pGraphic
,
45 , m_pGraphic( pGraphic
? new Graphic( *pGraphic
) : NULL
)
46 , m_nAspect( nAspect
)
50 TransferableObjectDescriptor aObjDesc
;
52 FillTransferableObjectDescriptor( aObjDesc
, m_xObj
, NULL
, m_nAspect
);
53 PrepareOLE( aObjDesc
);
57 // -----------------------------------------------------------------------------
59 SvEmbedTransferHelper::~SvEmbedTransferHelper()
68 // -----------------------------------------------------------------------------
70 void SvEmbedTransferHelper::AddSupportedFormats()
72 AddFormat( SOT_FORMATSTR_ID_EMBED_SOURCE
);
73 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
);
74 AddFormat( FORMAT_GDIMETAFILE
);
77 // -----------------------------------------------------------------------------
79 sal_Bool
SvEmbedTransferHelper::GetData( const ::com::sun::star::datatransfer::DataFlavor
& rFlavor
)
81 sal_Bool bRet
= sal_False
;
87 sal_uInt32 nFormat
= SotExchange::GetFormat( rFlavor
);
88 if( HasFormat( nFormat
) )
90 if( nFormat
== SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
)
92 TransferableObjectDescriptor aDesc
;
93 FillTransferableObjectDescriptor( aDesc
, m_xObj
, m_pGraphic
, m_nAspect
);
94 bRet
= SetTransferableObjectDescriptor( aDesc
, rFlavor
);
96 else if( nFormat
== SOT_FORMATSTR_ID_EMBED_SOURCE
)
100 // TODO/LATER: Propbably the graphic should be copied here as well
101 // currently it is handled by the applications
103 aTmp
.EnableKillingFile( sal_True
);
104 uno::Reference
< embed::XEmbedPersist
> xPers( m_xObj
, uno::UNO_QUERY
);
107 uno::Reference
< embed::XStorage
> xStg
= comphelper::OStorageHelper::GetTemporaryStorage();
108 OUString
aName( "Dummy" );
109 SvStream
* pStream
= NULL
;
110 sal_Bool bDeleteStream
= sal_False
;
111 uno::Sequence
< beans::PropertyValue
> aEmpty
;
112 xPers
->storeToEntry( xStg
, aName
, aEmpty
, aEmpty
);
113 if ( xStg
->isStreamElement( aName
) )
115 uno::Reference
< io::XStream
> xStm
= xStg
->cloneStreamElement( aName
);
116 pStream
= utl::UcbStreamHelper::CreateStream( xStm
);
117 bDeleteStream
= sal_True
;
121 pStream
= aTmp
.GetStream( STREAM_STD_READWRITE
);
122 uno::Reference
< embed::XStorage
> xStor
= comphelper::OStorageHelper::GetStorageFromStream( new utl::OStreamWrapper( *pStream
) );
123 xStg
->openStorageElement( aName
, embed::ElementModes::READ
)->copyToStorage( xStor
);
126 ::com::sun::star::uno::Any aAny
;
127 const sal_uInt32 nLen
= pStream
->Seek( STREAM_SEEK_TO_END
);
128 ::com::sun::star::uno::Sequence
< sal_Int8
> aSeq( nLen
);
130 pStream
->Seek( STREAM_SEEK_TO_BEGIN
);
131 pStream
->Read( aSeq
.getArray(), nLen
);
135 if( ( bRet
= ( aSeq
.getLength() > 0 ) ) == sal_True
)
138 SetAny( aAny
, rFlavor
);
143 //TODO/LATER: how to handle objects without persistance?!
146 catch ( uno::Exception
& )
150 else if ( nFormat
== FORMAT_GDIMETAFILE
&& m_pGraphic
)
152 SvMemoryStream
aMemStm( 65535, 65535 );
153 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
155 const GDIMetaFile
& aMetaFile
= m_pGraphic
->GetGDIMetaFile();
156 ((GDIMetaFile
*)(&aMetaFile
))->Write( aMemStm
);
158 aAny
<<= uno::Sequence
< sal_Int8
>( reinterpret_cast< const sal_Int8
* >( aMemStm
.GetData() ),
159 aMemStm
.Seek( STREAM_SEEK_TO_END
) );
160 SetAny( aAny
, rFlavor
);
163 else if ( m_xObj
.is() && :: svt::EmbeddedObjectRef::TryRunningState( m_xObj
) )
165 uno::Reference
< datatransfer::XTransferable
> xTransferable( m_xObj
->getComponent(), uno::UNO_QUERY
);
166 if ( xTransferable
.is() )
168 uno::Any aAny
= xTransferable
->getTransferData( rFlavor
);
169 SetAny( aAny
, rFlavor
);
175 catch( uno::Exception
& )
184 // -----------------------------------------------------------------------------
186 void SvEmbedTransferHelper::ObjectReleased()
188 m_xObj
= uno::Reference
< embed::XEmbeddedObject
>();
191 void SvEmbedTransferHelper::FillTransferableObjectDescriptor( TransferableObjectDescriptor
& rDesc
,
192 const ::com::sun::star::uno::Reference
< ::com::sun::star::embed::XEmbeddedObject
>& xObj
,
193 const Graphic
* pGraphic
,
196 //TODO/LATER: need TypeName to fill it into the Descriptor (will be shown in listbox)
197 ::com::sun::star::datatransfer::DataFlavor aFlavor
;
198 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR
, aFlavor
);
200 rDesc
.maClassName
= SvGlobalName( xObj
->getClassID() );
201 rDesc
.maTypeName
= aFlavor
.HumanPresentableName
;
203 //TODO/LATER: the aspect size in the descriptor is wrong, unfortunately the stream
204 // representation of the descriptor allows only 4 bytes for the aspect
205 // so for internal transport something different should be found
206 rDesc
.mnViewAspect
= sal::static_int_cast
<sal_uInt16
>( nAspect
);
208 //TODO/LATER: status needs to become sal_Int64
209 rDesc
.mnOle2Misc
= sal::static_int_cast
<sal_Int32
>(xObj
->getStatus( rDesc
.mnViewAspect
));
212 MapMode
aMapMode( MAP_100TH_MM
);
213 if ( nAspect
== embed::Aspects::MSOLE_ICON
)
217 aMapMode
= pGraphic
->GetPrefMapMode();
218 aSize
= pGraphic
->GetPrefSize();
221 aSize
= Size( 2500, 2500 );
228 aSz
= xObj
->getVisualAreaSize( rDesc
.mnViewAspect
);
229 aSize
= Size( aSz
.Width
, aSz
.Height
);
231 catch( embed::NoVisualAreaSizeException
& )
233 OSL_FAIL( "Can not get visual area size!\n" );
234 aSize
= Size( 5000, 5000 );
237 // TODO/LEAN: getMapUnit can switch object to running state
238 aMapMode
= MapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( rDesc
.mnViewAspect
) ) );
241 rDesc
.maSize
= OutputDevice::LogicToLogic( aSize
, aMapMode
, MapMode( MAP_100TH_MM
) );
242 rDesc
.maDragStartPos
= Point();
243 rDesc
.maDisplayName
= String();
244 rDesc
.mbCanLink
= sal_False
;
247 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */