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>
27 #include <sot/exchange.hxx>
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
);
59 SvEmbedTransferHelper::~SvEmbedTransferHelper()
68 void SvEmbedTransferHelper::SetParentShellID( const OUString
& rShellID
)
70 maParentShellID
= rShellID
;
74 void SvEmbedTransferHelper::AddSupportedFormats()
76 AddFormat( SotClipboardFormatId::EMBED_SOURCE
);
77 AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR
);
78 AddFormat( SotClipboardFormatId::GDIMETAFILE
);
79 AddFormat( SotClipboardFormatId::BITMAP
);
84 bool SvEmbedTransferHelper::GetData( const css::datatransfer::DataFlavor
& rFlavor
, const OUString
& rDestDoc
)
92 SotClipboardFormatId nFormat
= SotExchange::GetFormat( rFlavor
);
93 if( HasFormat( nFormat
) )
95 if( nFormat
== SotClipboardFormatId::OBJECTDESCRIPTOR
)
97 TransferableObjectDescriptor aDesc
;
98 FillTransferableObjectDescriptor( aDesc
, m_xObj
, m_pGraphic
, m_nAspect
);
99 bRet
= SetTransferableObjectDescriptor( aDesc
, rFlavor
);
101 else if( nFormat
== SotClipboardFormatId::EMBED_SOURCE
)
105 // TODO/LATER: Propbably the graphic should be copied here as well
106 // currently it is handled by the applications
108 aTmp
.EnableKillingFile( true );
109 uno::Reference
< embed::XEmbedPersist
> xPers( m_xObj
, uno::UNO_QUERY
);
112 uno::Reference
< embed::XStorage
> xStg
= comphelper::OStorageHelper::GetTemporaryStorage();
113 OUString
aName( "Dummy" );
114 SvStream
* pStream
= NULL
;
115 bool bDeleteStream
= false;
116 uno::Sequence
< beans::PropertyValue
> aEmpty
;
117 uno::Sequence
<beans::PropertyValue
> aObjArgs(2);
118 aObjArgs
[0].Name
= "SourceShellID";
119 aObjArgs
[0].Value
<<= maParentShellID
;
120 aObjArgs
[1].Name
= "DestinationShellID";
121 aObjArgs
[1].Value
<<= rDestDoc
;
122 xPers
->storeToEntry(xStg
, aName
, aEmpty
, aObjArgs
);
123 if ( xStg
->isStreamElement( aName
) )
125 uno::Reference
< io::XStream
> xStm
= xStg
->cloneStreamElement( aName
);
126 pStream
= utl::UcbStreamHelper::CreateStream( xStm
);
127 bDeleteStream
= true;
131 pStream
= aTmp
.GetStream( STREAM_STD_READWRITE
);
132 uno::Reference
< embed::XStorage
> xStor
= comphelper::OStorageHelper::GetStorageFromStream( new utl::OStreamWrapper( *pStream
) );
133 xStg
->openStorageElement( aName
, embed::ElementModes::READ
)->copyToStorage( xStor
);
136 ::com::sun::star::uno::Any aAny
;
137 const sal_uInt32 nLen
= pStream
->Seek( STREAM_SEEK_TO_END
);
138 ::com::sun::star::uno::Sequence
< sal_Int8
> aSeq( nLen
);
140 pStream
->Seek( STREAM_SEEK_TO_BEGIN
);
141 pStream
->Read( aSeq
.getArray(), nLen
);
145 if( ( bRet
= ( aSeq
.getLength() > 0 ) ) )
148 SetAny( aAny
, rFlavor
);
153 //TODO/LATER: how to handle objects without persistence?!
156 catch ( uno::Exception
& )
160 else if ( nFormat
== SotClipboardFormatId::GDIMETAFILE
&& m_pGraphic
)
162 SvMemoryStream
aMemStm( 65535, 65535 );
163 aMemStm
.SetVersion( SOFFICE_FILEFORMAT_CURRENT
);
165 const GDIMetaFile
& aMetaFile
= m_pGraphic
->GetGDIMetaFile();
166 const_cast<GDIMetaFile
*>(&aMetaFile
)->Write( aMemStm
);
168 aAny
<<= uno::Sequence
< sal_Int8
>( static_cast< const sal_Int8
* >( aMemStm
.GetData() ),
169 aMemStm
.Seek( STREAM_SEEK_TO_END
) );
170 SetAny( aAny
, rFlavor
);
173 else if ( ( nFormat
== SotClipboardFormatId::BITMAP
|| nFormat
== SotClipboardFormatId::PNG
) && m_pGraphic
)
175 bRet
= SetBitmapEx( m_pGraphic
->GetBitmapEx(), rFlavor
);
177 else if ( m_xObj
.is() && :: svt::EmbeddedObjectRef::TryRunningState( m_xObj
) )
179 uno::Reference
< datatransfer::XTransferable
> xTransferable( m_xObj
->getComponent(), uno::UNO_QUERY
);
180 if ( xTransferable
.is() )
182 uno::Any aAny
= xTransferable
->getTransferData( rFlavor
);
183 SetAny( aAny
, rFlavor
);
189 catch( uno::Exception
& )
200 void SvEmbedTransferHelper::ObjectReleased()
202 m_xObj
= uno::Reference
< embed::XEmbeddedObject
>();
205 void SvEmbedTransferHelper::FillTransferableObjectDescriptor( TransferableObjectDescriptor
& rDesc
,
206 const ::com::sun::star::uno::Reference
< ::com::sun::star::embed::XEmbeddedObject
>& xObj
,
207 const Graphic
* pGraphic
,
210 //TODO/LATER: need TypeName to fill it into the Descriptor (will be shown in listbox)
211 ::com::sun::star::datatransfer::DataFlavor aFlavor
;
212 SotExchange::GetFormatDataFlavor( SotClipboardFormatId::OBJECTDESCRIPTOR
, aFlavor
);
214 rDesc
.maClassName
= SvGlobalName( xObj
->getClassID() );
215 rDesc
.maTypeName
= aFlavor
.HumanPresentableName
;
217 //TODO/LATER: the aspect size in the descriptor is wrong, unfortunately the stream
218 // representation of the descriptor allows only 4 bytes for the aspect
219 // so for internal transport something different should be found
220 rDesc
.mnViewAspect
= sal::static_int_cast
<sal_uInt16
>( nAspect
);
222 //TODO/LATER: status needs to become sal_Int64
223 rDesc
.mnOle2Misc
= sal::static_int_cast
<sal_Int32
>(xObj
->getStatus( rDesc
.mnViewAspect
));
226 MapMode
aMapMode( MAP_100TH_MM
);
227 if ( nAspect
== embed::Aspects::MSOLE_ICON
)
231 aMapMode
= pGraphic
->GetPrefMapMode();
232 aSize
= pGraphic
->GetPrefSize();
235 aSize
= Size( 2500, 2500 );
242 aSz
= xObj
->getVisualAreaSize( rDesc
.mnViewAspect
);
243 aSize
= Size( aSz
.Width
, aSz
.Height
);
245 catch( embed::NoVisualAreaSizeException
& )
247 OSL_FAIL( "Can not get visual area size!\n" );
248 aSize
= Size( 5000, 5000 );
251 // TODO/LEAN: getMapUnit can switch object to running state
252 aMapMode
= MapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj
->getMapUnit( rDesc
.mnViewAspect
) ) );
255 rDesc
.maSize
= OutputDevice::LogicToLogic( aSize
, aMapMode
, MapMode( MAP_100TH_MM
) );
256 rDesc
.maDragStartPos
= Point();
257 rDesc
.maDisplayName
.clear();
258 rDesc
.mbCanLink
= false;
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */