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