Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <com/sun/star/lang/DisposedException.hpp>
30 : : #include <com/sun/star/embed/EmbedStates.hpp>
31 : : #include <com/sun/star/embed/EmbedMapUnits.hpp>
32 : : #include <com/sun/star/embed/EmbedMisc.hpp>
33 : : #include <com/sun/star/embed/Aspects.hpp>
34 : : #include <com/sun/star/io/XSeekable.hpp>
35 : : #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
36 : :
37 : : #include <rtl/logfile.hxx>
38 : :
39 : : #include <oleembobj.hxx>
40 : : #include <olecomponent.hxx>
41 : : #include <comphelper/mimeconfighelper.hxx>
42 : : #include <comphelper/seqstream.hxx>
43 : :
44 : : using namespace ::com::sun::star;
45 : : using namespace ::comphelper;
46 : :
47 : 0 : embed::VisualRepresentation OleEmbeddedObject::GetVisualRepresentationInNativeFormat_Impl(
48 : : const uno::Reference< io::XStream > xCachedVisRepr )
49 : : throw ( uno::Exception )
50 : : {
51 : 0 : embed::VisualRepresentation aVisualRepr;
52 : :
53 : : // TODO: detect the format in the future for now use workaround
54 [ # # ][ # # ]: 0 : uno::Reference< io::XInputStream > xInStream = xCachedVisRepr->getInputStream();
55 [ # # ]: 0 : uno::Reference< io::XSeekable > xSeekable( xCachedVisRepr, uno::UNO_QUERY );
56 [ # # ][ # # ]: 0 : if ( !xInStream.is() || !xSeekable.is() )
[ # # ]
57 [ # # ]: 0 : throw uno::RuntimeException();
58 : :
59 [ # # ]: 0 : uno::Sequence< sal_Int8 > aSeq( 2 );
60 [ # # ][ # # ]: 0 : xInStream->readBytes( aSeq, 2 );
61 [ # # ][ # # ]: 0 : xSeekable->seek( 0 );
62 [ # # ][ # # ]: 0 : if ( aSeq.getLength() == 2 && aSeq[0] == 'B' && aSeq[1] == 'M' )
[ # # ][ # # ]
[ # # ][ # # ]
63 : : {
64 : : // it's a bitmap
65 : : aVisualRepr.Flavor = datatransfer::DataFlavor(
66 : : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" )),
67 : : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Bitmap" )),
68 [ # # ][ # # ]: 0 : ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
[ # # ]
69 : : }
70 : : else
71 : : {
72 : : // it's a metafile
73 : : aVisualRepr.Flavor = datatransfer::DataFlavor(
74 : : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )),
75 : : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Windows Metafile" )),
76 [ # # ][ # # ]: 0 : ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
[ # # ]
77 : : }
78 : :
79 [ # # ][ # # ]: 0 : sal_Int32 nStreamLength = (sal_Int32)xSeekable->getLength();
80 [ # # ]: 0 : uno::Sequence< sal_Int8 > aRepresent( nStreamLength );
81 [ # # ][ # # ]: 0 : xInStream->readBytes( aRepresent, nStreamLength );
82 [ # # ]: 0 : aVisualRepr.Data <<= aRepresent;
83 : :
84 [ # # ][ # # ]: 0 : return aVisualRepr;
85 : : }
86 : :
87 : 0 : void SAL_CALL OleEmbeddedObject::setVisualAreaSize( sal_Int64 nAspect, const awt::Size& aSize )
88 : : throw ( lang::IllegalArgumentException,
89 : : embed::WrongStateException,
90 : : uno::Exception,
91 : : uno::RuntimeException )
92 : : {
93 : : RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::setVisualAreaSize" );
94 : :
95 : : // begin wrapping related part ====================
96 : 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
97 [ # # ]: 0 : if ( xWrappedObject.is() )
98 : : {
99 : : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
100 [ # # ][ # # ]: 0 : xWrappedObject->setVisualAreaSize( nAspect, aSize );
101 : 0 : return;
102 : : }
103 : : // end wrapping related part ====================
104 : :
105 [ # # ]: 0 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
106 [ # # ]: 0 : if ( m_bDisposed )
107 [ # # ]: 0 : throw lang::DisposedException(); // TODO
108 : :
109 : : OSL_ENSURE( nAspect != embed::Aspects::MSOLE_ICON, "For iconified objects no graphical replacement is required!\n" );
110 [ # # ]: 0 : if ( nAspect == embed::Aspects::MSOLE_ICON )
111 : : // no representation can be retrieved
112 : : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Illegal call!\n" )),
113 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
114 : :
115 [ # # ]: 0 : if ( m_nObjectState == -1 )
116 : : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object is not loaded!\n" )),
117 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
118 : :
119 : : #ifdef WNT
120 : : // RECOMPOSE_ON_RESIZE misc flag means that the object has to be switched to running state on resize.
121 : : // SetExtent() is called only for objects that require it,
122 : : // it should not be called for MSWord documents to workaround problem i49369
123 : : // If cached size is not set, that means that this is the size initialization, so there is no need to set the real size
124 : : sal_Bool bAllowToSetExtent =
125 : : ( ( getStatus( nAspect ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE )
126 : : && !MimeConfigurationHelper::ClassIDsEqual( m_aClassID, MimeConfigurationHelper::GetSequenceClassID( 0x00020906L, 0x0000, 0x0000,
127 : : 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ) )
128 : : && m_bHasCachedSize );
129 : :
130 : : if ( m_nObjectState == embed::EmbedStates::LOADED && bAllowToSetExtent )
131 : : {
132 : : aGuard.clear();
133 : : try {
134 : : changeState( embed::EmbedStates::RUNNING );
135 : : }
136 : : catch( const uno::Exception& )
137 : : {
138 : : OSL_FAIL( "The object should not be resized without activation!\n" );
139 : : }
140 : : aGuard.reset();
141 : : }
142 : :
143 : : if ( m_pOleComponent && m_nObjectState != embed::EmbedStates::LOADED && bAllowToSetExtent )
144 : : {
145 : : awt::Size aSizeToSet = aSize;
146 : : aGuard.clear();
147 : : try {
148 : : m_pOleComponent->SetExtent( aSizeToSet, nAspect ); // will throw an exception in case of failure
149 : : m_bHasSizeToSet = sal_False;
150 : : }
151 : : catch( const uno::Exception& )
152 : : {
153 : : // some objects do not allow to set the size even in running state
154 : : m_bHasSizeToSet = sal_True;
155 : : m_aSizeToSet = aSizeToSet;
156 : : m_nAspectToSet = nAspect;
157 : : }
158 : : aGuard.reset();
159 : : }
160 : : #endif
161 : :
162 : : // cache the values
163 : 0 : m_bHasCachedSize = sal_True;
164 : 0 : m_aCachedSize = aSize;
165 [ # # ][ # # ]: 0 : m_nCachedAspect = nAspect;
166 : : }
167 : :
168 : 0 : awt::Size SAL_CALL OleEmbeddedObject::getVisualAreaSize( sal_Int64 nAspect )
169 : : throw ( lang::IllegalArgumentException,
170 : : embed::WrongStateException,
171 : : uno::Exception,
172 : : uno::RuntimeException )
173 : : {
174 : : RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::getVisualAreaSize" );
175 : :
176 : : // begin wrapping related part ====================
177 : 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
178 [ # # ]: 0 : if ( xWrappedObject.is() )
179 : : {
180 : : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
181 [ # # ][ # # ]: 0 : return xWrappedObject->getVisualAreaSize( nAspect );
182 : : }
183 : : // end wrapping related part ====================
184 : :
185 [ # # ]: 0 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
186 [ # # ]: 0 : if ( m_bDisposed )
187 [ # # ]: 0 : throw lang::DisposedException(); // TODO
188 : :
189 : : OSL_ENSURE( nAspect != embed::Aspects::MSOLE_ICON, "For iconified objects no graphical replacement is required!\n" );
190 [ # # ]: 0 : if ( nAspect == embed::Aspects::MSOLE_ICON )
191 : : // no representation can be retrieved
192 : : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Illegal call!\n" )),
193 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
194 : :
195 [ # # ]: 0 : if ( m_nObjectState == -1 )
196 : : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object is not loaded!\n" )),
197 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
198 : :
199 : 0 : awt::Size aResult;
200 : :
201 : : #ifdef WNT
202 : : // TODO/LATER: Support different aspects
203 : : if ( m_pOleComponent && !m_bHasSizeToSet && nAspect == embed::Aspects::MSOLE_CONTENT )
204 : : {
205 : : try
206 : : {
207 : : // the cached size updated every time the object is stored
208 : : if ( m_bHasCachedSize )
209 : : {
210 : : aResult = m_aCachedSize;
211 : : }
212 : : else
213 : : {
214 : : // there is no internal cache
215 : : awt::Size aSize;
216 : : aGuard.clear();
217 : :
218 : : sal_Bool bSuccess = sal_False;
219 : : if ( getCurrentState() == embed::EmbedStates::LOADED )
220 : : {
221 : : OSL_FAIL( "Loaded object has no cached size!\n" );
222 : :
223 : : // try to switch the object to RUNNING state and request the value again
224 : : try {
225 : : changeState( embed::EmbedStates::RUNNING );
226 : : }
227 : : catch( const uno::Exception& )
228 : : {
229 : : throw embed::NoVisualAreaSizeException(
230 : : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No size available!\n" ) ),
231 : : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
232 : : }
233 : : }
234 : :
235 : : try
236 : : {
237 : : // first try to get size using replacement image
238 : : aSize = m_pOleComponent->GetExtent( nAspect ); // will throw an exception in case of failure
239 : : bSuccess = sal_True;
240 : : }
241 : : catch( const uno::Exception& )
242 : : {
243 : : }
244 : :
245 : : if ( !bSuccess )
246 : : {
247 : : try
248 : : {
249 : : // second try the cached replacement image
250 : : aSize = m_pOleComponent->GetCachedExtent( nAspect ); // will throw an exception in case of failure
251 : : bSuccess = sal_True;
252 : : }
253 : : catch( const uno::Exception& )
254 : : {
255 : : }
256 : : }
257 : :
258 : : if ( !bSuccess )
259 : : {
260 : : try
261 : : {
262 : : // third try the size reported by the object
263 : : aSize = m_pOleComponent->GetReccomendedExtent( nAspect ); // will throw an exception in case of failure
264 : : bSuccess = sal_True;
265 : : }
266 : : catch( const uno::Exception& )
267 : : {
268 : : }
269 : : }
270 : :
271 : : if ( !bSuccess )
272 : : throw embed::NoVisualAreaSizeException(
273 : : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No size available!\n" ) ),
274 : : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
275 : :
276 : : aGuard.reset();
277 : :
278 : : m_aCachedSize = aSize;
279 : : m_nCachedAspect = nAspect;
280 : : m_bHasCachedSize = sal_True;
281 : :
282 : : aResult = m_aCachedSize;
283 : : }
284 : : }
285 : : catch ( const embed::NoVisualAreaSizeException& )
286 : : {
287 : : throw;
288 : : }
289 : : catch ( const uno::Exception& )
290 : : {
291 : : throw embed::NoVisualAreaSizeException(
292 : : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No size available!\n" ) ),
293 : : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
294 : : }
295 : : }
296 : : else
297 : : #endif
298 : : {
299 : : // return cached value
300 [ # # ]: 0 : if ( m_bHasCachedSize )
301 : : {
302 : : OSL_ENSURE( nAspect == m_nCachedAspect, "Unexpected aspect is requested!\n" );
303 : 0 : aResult = m_aCachedSize;
304 : : }
305 : : else
306 : : {
307 : : throw embed::NoVisualAreaSizeException(
308 : : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No size available!\n" ) ),
309 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
310 : : }
311 : : }
312 : :
313 [ # # ]: 0 : return aResult;
314 : : }
315 : :
316 : 0 : embed::VisualRepresentation SAL_CALL OleEmbeddedObject::getPreferredVisualRepresentation( sal_Int64 nAspect )
317 : : throw ( lang::IllegalArgumentException,
318 : : embed::WrongStateException,
319 : : uno::Exception,
320 : : uno::RuntimeException )
321 : : {
322 : : RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::getPreferredVisualRepresentation" );
323 : :
324 : : // begin wrapping related part ====================
325 : 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
326 [ # # ]: 0 : if ( xWrappedObject.is() )
327 : : {
328 : : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
329 [ # # ][ # # ]: 0 : return xWrappedObject->getPreferredVisualRepresentation( nAspect );
330 : : }
331 : : // end wrapping related part ====================
332 : :
333 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
334 [ # # ]: 0 : if ( m_bDisposed )
335 [ # # ]: 0 : throw lang::DisposedException(); // TODO
336 : :
337 : : OSL_ENSURE( nAspect != embed::Aspects::MSOLE_ICON, "For iconified objects no graphical replacement is required!\n" );
338 [ # # ]: 0 : if ( nAspect == embed::Aspects::MSOLE_ICON )
339 : : // no representation can be retrieved
340 : : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Illegal call!\n" )),
341 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
342 : :
343 : : // TODO: if the object has cached representation then it should be returned
344 : : // TODO: if the object has no cached representation and is in loaded state it should switch itself to the running state
345 [ # # ]: 0 : if ( m_nObjectState == -1 )
346 : : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object is not loaded!\n" )),
347 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
348 : :
349 : 0 : embed::VisualRepresentation aVisualRepr;
350 : :
351 : : // TODO: in case of different aspects they must be applied to the mediatype and XTransferable must be used
352 : : // the cache is used only as a fallback if object is not in loaded state
353 [ # # ][ # # ]: 0 : if ( !m_xCachedVisualRepresentation.is() && ( !m_bVisReplInitialized || m_bVisReplInStream )
[ # # ][ # # ]
[ # # ]
354 : : && m_nObjectState == embed::EmbedStates::LOADED )
355 : : {
356 [ # # ]: 0 : m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream, sal_True );
357 [ # # ]: 0 : SetVisReplInStream( m_xCachedVisualRepresentation.is() );
358 : : }
359 : :
360 [ # # ]: 0 : if ( m_xCachedVisualRepresentation.is() )
361 : : {
362 [ # # ]: 0 : return GetVisualRepresentationInNativeFormat_Impl( m_xCachedVisualRepresentation );
363 : : }
364 : : #ifdef WNT
365 : : else if ( m_pOleComponent )
366 : : {
367 : : try
368 : : {
369 : : if ( m_nObjectState == embed::EmbedStates::LOADED )
370 : : changeState( embed::EmbedStates::RUNNING );
371 : :
372 : : datatransfer::DataFlavor aDataFlavor(
373 : : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )),
374 : : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Windows Metafile" )),
375 : : ::getCppuType( (const uno::Sequence< sal_Int8 >*) NULL ) );
376 : :
377 : : aVisualRepr.Data = m_pOleComponent->getTransferData( aDataFlavor );
378 : : aVisualRepr.Flavor = aDataFlavor;
379 : :
380 : : uno::Sequence< sal_Int8 > aVisReplSeq;
381 : : aVisualRepr.Data >>= aVisReplSeq;
382 : : if ( aVisReplSeq.getLength() )
383 : : {
384 : : m_xCachedVisualRepresentation = GetNewFilledTempStream_Impl(
385 : : uno::Reference< io::XInputStream > ( static_cast< io::XInputStream* > (
386 : : new ::comphelper::SequenceInputStream( aVisReplSeq ) ) ) );
387 : : }
388 : :
389 : : return aVisualRepr;
390 : : }
391 : : catch( const uno::Exception& )
392 : : {}
393 : : }
394 : : #endif
395 : :
396 : : // the cache is used only as a fallback if object is not in loaded state
397 [ # # ][ # # ]: 0 : if ( !m_xCachedVisualRepresentation.is() && ( !m_bVisReplInitialized || m_bVisReplInStream ) )
[ # # ][ # # ]
398 : : {
399 [ # # ]: 0 : m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream );
400 [ # # ]: 0 : SetVisReplInStream( m_xCachedVisualRepresentation.is() );
401 : : }
402 : :
403 [ # # ]: 0 : if ( !m_xCachedVisualRepresentation.is() )
404 : : {
405 : : // no representation can be retrieved
406 : : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Illegal call!\n" )),
407 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
408 : : }
409 : :
410 [ # # ][ # # ]: 0 : return GetVisualRepresentationInNativeFormat_Impl( m_xCachedVisualRepresentation );
411 : : }
412 : :
413 : 0 : sal_Int32 SAL_CALL OleEmbeddedObject::getMapUnit( sal_Int64 nAspect )
414 : : throw ( uno::Exception,
415 : : uno::RuntimeException)
416 : : {
417 : : // begin wrapping related part ====================
418 : 0 : uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
419 [ # # ]: 0 : if ( xWrappedObject.is() )
420 : : {
421 : : // the object was converted to OOo embedded object, the current implementation is now only a wrapper
422 [ # # ][ # # ]: 0 : return xWrappedObject->getMapUnit( nAspect );
423 : : }
424 : : // end wrapping related part ====================
425 : :
426 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
427 [ # # ]: 0 : if ( m_bDisposed )
428 [ # # ]: 0 : throw lang::DisposedException(); // TODO
429 : :
430 : : OSL_ENSURE( nAspect != embed::Aspects::MSOLE_ICON, "For iconified objects no graphical replacement is required!\n" );
431 [ # # ]: 0 : if ( nAspect == embed::Aspects::MSOLE_ICON )
432 : : // no representation can be retrieved
433 : : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Illegal call!\n" )),
434 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
435 : :
436 [ # # ]: 0 : if ( m_nObjectState == -1 )
437 : : throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object is not loaded!\n" )),
438 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
[ # # ]
439 : :
440 [ # # ]: 0 : return embed::EmbedMapUnits::ONE_100TH_MM;
441 : : }
442 : :
443 : :
444 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|