Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / embeddedobj / source / msole / olepersist.cxx
blobefb51d39ff3317526601b4e05c02171d1dc0742b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
29 #include <oleembobj.hxx>
30 #include <com/sun/star/embed/EmbedStates.hpp>
31 #include <com/sun/star/embed/EmbedVerbs.hpp>
32 #include <com/sun/star/embed/EntryInitModes.hpp>
33 #include <com/sun/star/embed/XStorage.hpp>
34 #include <com/sun/star/embed/XTransactedObject.hpp>
35 #include <com/sun/star/embed/ElementModes.hpp>
36 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
37 #include <com/sun/star/embed/Aspects.hpp>
38 #include <com/sun/star/embed/XOptimizedStorage.hpp>
39 #include <com/sun/star/lang/XComponent.hpp>
40 #include <com/sun/star/lang/DisposedException.hpp>
41 #include <com/sun/star/container/XNameAccess.hpp>
42 #include <com/sun/star/container/XNameContainer.hpp>
43 #include <com/sun/star/io/XSeekable.hpp>
44 #include <com/sun/star/io/XTruncate.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
48 #include <rtl/logfile.hxx>
50 #include <comphelper/storagehelper.hxx>
51 #include <comphelper/mimeconfighelper.hxx>
52 #include <comphelper/classids.hxx>
55 #include <olecomponent.hxx>
56 #include <closepreventer.hxx>
58 using namespace ::com::sun::star;
59 using namespace ::comphelper;
61 //-------------------------------------------------------------------------
62 sal_Bool KillFile_Impl( const ::rtl::OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
64 if ( !xFactory.is() )
65 return sal_False;
67 sal_Bool bRet = sal_False;
69 try
71 uno::Reference < ucb::XSimpleFileAccess > xAccess(
72 xFactory->createInstance (
73 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) )),
74 uno::UNO_QUERY );
76 if ( xAccess.is() )
78 xAccess->kill( aURL );
79 bRet = sal_True;
82 catch( const uno::Exception& )
86 return bRet;
89 //----------------------------------------------
90 ::rtl::OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
92 OSL_ENSURE( xFactory.is(), "No factory is provided!\n" );
94 ::rtl::OUString aResult;
96 uno::Reference < beans::XPropertySet > xTempFile(
97 xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) )),
98 uno::UNO_QUERY );
100 if ( !xTempFile.is() )
101 throw uno::RuntimeException(); // TODO
103 try {
104 xTempFile->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RemoveFile" )), uno::makeAny( sal_False ) );
105 uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ));
106 aUrl >>= aResult;
108 catch ( const uno::Exception& )
112 if ( aResult.isEmpty() )
113 throw uno::RuntimeException(); // TODO: can not create tempfile
115 return aResult;
118 //-----------------------------------------------
119 ::rtl::OUString GetNewFilledTempFile_Impl( const uno::Reference< io::XInputStream >& xInStream,
120 const uno::Reference< lang::XMultiServiceFactory >& xFactory )
121 throw ( io::IOException,
122 uno::RuntimeException )
124 OSL_ENSURE( xInStream.is() && xFactory.is(), "Wrong parameters are provided!\n" );
126 ::rtl::OUString aResult = GetNewTempFileURL_Impl( xFactory );
128 if ( !aResult.isEmpty() )
130 try {
131 uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
132 xFactory->createInstance (
133 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) )),
134 uno::UNO_QUERY );
136 if ( !xTempAccess.is() )
137 throw uno::RuntimeException(); // TODO:
139 uno::Reference< io::XOutputStream > xTempOutStream = xTempAccess->openFileWrite( aResult );
140 if ( xTempOutStream.is() )
142 // copy stream contents to the file
143 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOutStream );
144 xTempOutStream->closeOutput();
145 xTempOutStream = uno::Reference< io::XOutputStream >();
147 else
148 throw io::IOException(); // TODO:
150 catch( const packages::WrongPasswordException& )
152 KillFile_Impl( aResult, xFactory );
153 throw io::IOException(); //TODO:
155 catch( const io::IOException& )
157 KillFile_Impl( aResult, xFactory );
158 throw;
160 catch( const uno::RuntimeException& )
162 KillFile_Impl( aResult, xFactory );
163 throw;
165 catch( const uno::Exception& )
167 KillFile_Impl( aResult, xFactory );
168 aResult = ::rtl::OUString();
172 return aResult;
174 #ifdef WNT
175 ::rtl::OUString GetNewFilledTempFile_Impl( const uno::Reference< embed::XOptimizedStorage >& xParentStorage, const ::rtl::OUString& aEntryName, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
176 throw( io::IOException, uno::RuntimeException )
178 ::rtl::OUString aResult;
182 uno::Reference < beans::XPropertySet > xTempFile(
183 xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) )),
184 uno::UNO_QUERY );
185 uno::Reference < io::XStream > xTempStream( xTempFile, uno::UNO_QUERY_THROW );
187 xParentStorage->copyStreamElementData( aEntryName, xTempStream );
189 xTempFile->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RemoveFile" )), uno::makeAny( sal_False ) );
190 uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ));
191 aUrl >>= aResult;
193 catch( const uno::RuntimeException& )
195 throw;
197 catch( const uno::Exception& )
201 if ( aResult.isEmpty() )
202 throw io::IOException();
204 return aResult;
207 //------------------------------------------------------
208 void SetStreamMediaType_Impl( const uno::Reference< io::XStream >& xStream, const ::rtl::OUString& aMediaType )
210 uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY );
211 if ( !xPropSet.is() )
212 throw uno::RuntimeException(); // TODO: all the storage streams must support XPropertySet
214 xPropSet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MediaType" )), uno::makeAny( aMediaType ) );
216 #endif
217 //------------------------------------------------------
218 void LetCommonStoragePassBeUsed_Impl( const uno::Reference< io::XStream >& xStream )
220 uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY );
221 if ( !xPropSet.is() )
222 throw uno::RuntimeException(); // Only StorageStreams must be provided here, they must implement the interface
224 xPropSet->setPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" )),
225 uno::makeAny( (sal_Bool)sal_True ) );
227 #ifdef WNT
228 //------------------------------------------------------
229 void VerbExecutionController::StartControlExecution()
231 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
233 // the class is used to detect STAMPIT object, that can never be active
234 if ( !m_bVerbExecutionInProgress && !m_bWasEverActive )
236 m_bVerbExecutionInProgress = sal_True;
237 m_nVerbExecutionThreadIdentifier = osl_getThreadIdentifier( NULL );
238 m_bChangedOnVerbExecution = sal_False;
242 //------------------------------------------------------
243 sal_Bool VerbExecutionController::EndControlExecution_WasModified()
245 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
247 sal_Bool bResult = sal_False;
248 if ( m_bVerbExecutionInProgress && m_nVerbExecutionThreadIdentifier == osl_getThreadIdentifier( NULL ) )
250 bResult = m_bChangedOnVerbExecution;
251 m_bVerbExecutionInProgress = sal_False;
254 return bResult;
257 //------------------------------------------------------
258 void VerbExecutionController::ModificationNotificationIsDone()
260 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
262 if ( m_bVerbExecutionInProgress && osl_getThreadIdentifier( NULL ) == m_nVerbExecutionThreadIdentifier )
263 m_bChangedOnVerbExecution = sal_True;
265 #endif
266 //-----------------------------------------------
267 void VerbExecutionController::LockNotification()
269 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
270 if ( m_nNotificationLock < SAL_MAX_INT32 )
271 m_nNotificationLock++;
274 //-----------------------------------------------
275 void VerbExecutionController::UnlockNotification()
277 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
278 if ( m_nNotificationLock > 0 )
279 m_nNotificationLock--;
282 //-----------------------------------------------
283 uno::Reference< io::XStream > OleEmbeddedObject::GetNewFilledTempStream_Impl( const uno::Reference< io::XInputStream >& xInStream )
284 throw( io::IOException )
286 OSL_ENSURE( xInStream.is(), "Wrong parameter is provided!\n" );
288 uno::Reference < io::XStream > xTempFile(
289 m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) )),
290 uno::UNO_QUERY_THROW );
292 uno::Reference< io::XOutputStream > xTempOutStream = xTempFile->getOutputStream();
293 if ( xTempOutStream.is() )
295 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOutStream );
296 xTempOutStream->flush();
298 else
299 throw io::IOException(); // TODO:
301 return xTempFile;
304 //------------------------------------------------------
305 uno::Reference< io::XStream > OleEmbeddedObject::TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream )
306 throw ( uno::Exception )
308 // TODO/LATER: Actually this should be done by a centralized component ( may be a graphical filter )
309 if ( !m_xFactory.is() )
310 throw uno::RuntimeException();
312 uno::Reference< io::XInputStream > xInStream = xStream->getInputStream();
313 if ( !xInStream.is() )
314 throw uno::RuntimeException();
316 uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
317 xSeek->seek( 0 );
319 uno::Sequence< sal_Int8 > aData( 8 );
320 sal_Int32 nRead = xInStream->readBytes( aData, 8 );
321 xSeek->seek( 0 );
323 if ( ( nRead >= 2 && aData[0] == 'B' && aData[1] == 'M' )
324 || ( nRead >= 4 && aData[0] == 1 && aData[1] == 0 && aData[2] == 9 && aData[3] == 0 ) )
326 // it should be a bitmap or a Metafile
327 return xStream;
331 sal_uInt32 nHeaderOffset = 0;
332 if ( ( nRead >= 8 && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1 )
333 && ( aData[4] == 2 || aData[4] == 3 || aData[4] == 14 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
335 nHeaderOffset = 40;
336 xSeek->seek( 8 );
338 // TargetDevice might be used in future, currently the cache has specified NULL
339 uno::Sequence< sal_Int8 > aHeadData( 4 );
340 nRead = xInStream->readBytes( aHeadData, 4 );
341 sal_uInt32 nLen = 0;
342 if ( nRead == 4 && aHeadData.getLength() == 4 )
343 nLen = ( ( ( (sal_uInt32)aHeadData[3] * 0x100 + (sal_uInt32)aHeadData[2] ) * 0x100 ) + (sal_uInt32)aHeadData[1] ) * 0x100 + (sal_uInt32)aHeadData[0];
344 if ( nLen > 4 )
346 xInStream->skipBytes( nLen - 4 );
347 nHeaderOffset += nLen - 4;
351 else if ( nRead > 4 )
353 // check whether the first bytes represent the size
354 sal_uInt32 nSize = 0;
355 for ( sal_Int32 nInd = 3; nInd >= 0; nInd-- )
356 nSize = ( nSize << 8 ) + (sal_uInt8)aData[nInd];
358 if ( nSize == xSeek->getLength() - 4 )
359 nHeaderOffset = 4;
362 if ( nHeaderOffset )
364 // this is either a bitmap or a metafile clipboard format, retrieve the pure stream
365 uno::Reference < io::XStream > xResult(
366 m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) )),
367 uno::UNO_QUERY_THROW );
368 uno::Reference < io::XSeekable > xResultSeek( xResult, uno::UNO_QUERY_THROW );
369 uno::Reference < io::XOutputStream > xResultOut = xResult->getOutputStream();
370 uno::Reference < io::XInputStream > xResultIn = xResult->getInputStream();
371 if ( !xResultOut.is() || !xResultIn.is() )
372 throw uno::RuntimeException();
374 xSeek->seek( nHeaderOffset ); // header size for these formats
375 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xResultOut );
376 xResultOut->closeOutput();
377 xResultSeek->seek( 0 );
378 xSeek->seek( 0 );
380 return xResult;
383 return uno::Reference< io::XStream >();
386 //------------------------------------------------------
387 void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStream >& xTargetStream,
388 const uno::Reference< io::XStream >& xCachedVisualRepresentation )
389 throw ( uno::Exception )
391 OSL_ENSURE( xTargetStream.is() && xCachedVisualRepresentation.is(), "Invalid argumants!\n" );
393 if ( !xTargetStream.is() || !xCachedVisualRepresentation.is() )
394 throw uno::RuntimeException();
396 uno::Sequence< uno::Any > aArgs( 2 );
397 aArgs[0] <<= xTargetStream;
398 aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
400 uno::Reference< container::XNameContainer > xNameContainer(
401 m_xFactory->createInstanceWithArguments(
402 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLESimpleStorage" )),
403 aArgs ),
404 uno::UNO_QUERY );
406 if ( !xNameContainer.is() )
407 throw uno::RuntimeException();
409 uno::Reference< io::XSeekable > xCachedSeek( xCachedVisualRepresentation, uno::UNO_QUERY_THROW );
410 if ( xCachedSeek.is() )
411 xCachedSeek->seek( 0 );
413 uno::Reference < io::XStream > xTempFile(
414 m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) )),
415 uno::UNO_QUERY_THROW );
417 uno::Reference< io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY_THROW );
418 uno::Reference< io::XOutputStream > xTempOutStream = xTempFile->getOutputStream();
419 if ( xTempOutStream.is() )
421 // the OlePres stream must have additional header
422 // TODO/LATER: might need to be extended in future ( actually makes sence only for SO7 format )
423 uno::Reference< io::XInputStream > xInCacheStream = xCachedVisualRepresentation->getInputStream();
424 if ( !xInCacheStream.is() )
425 throw uno::RuntimeException();
427 // write 0xFFFFFFFF at the beginning
428 uno::Sequence< sal_Int8 > aData( 4 );
429 *( (sal_uInt32*)aData.getArray() ) = 0xFFFFFFFF;
431 xTempOutStream->writeBytes( aData );
433 // write clipboard format
434 uno::Sequence< sal_Int8 > aSigData( 2 );
435 xInCacheStream->readBytes( aSigData, 2 );
436 if ( aSigData.getLength() < 2 )
437 throw io::IOException();
439 if ( aSigData[0] == 'B' && aSigData[1] == 'M' )
441 // it's a bitmap
442 aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0;
444 else
446 // treat it as a metafile
447 aData[0] = 0x03; aData[1] = 0; aData[2] = 0; aData[3] = 0;
449 xTempOutStream->writeBytes( aData );
451 // write job related information
452 aData[0] = 0x04; aData[1] = 0; aData[2] = 0; aData[3] = 0;
453 xTempOutStream->writeBytes( aData );
455 // write aspect
456 aData[0] = 0x01; aData[1] = 0; aData[2] = 0; aData[3] = 0;
457 xTempOutStream->writeBytes( aData );
459 // write l-index
460 *( (sal_uInt32*)aData.getArray() ) = 0xFFFFFFFF;
461 xTempOutStream->writeBytes( aData );
463 // write adv. flags
464 aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0;
465 xTempOutStream->writeBytes( aData );
467 // write compression
468 *( (sal_uInt32*)aData.getArray() ) = 0x0;
469 xTempOutStream->writeBytes( aData );
471 // get the size
472 awt::Size aSize = getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
473 sal_Int32 nIndex = 0;
475 // write width
476 for ( nIndex = 0; nIndex < 4; nIndex++ )
478 aData[nIndex] = (sal_Int8)( aSize.Width % 0x100 );
479 aSize.Width /= 0x100;
481 xTempOutStream->writeBytes( aData );
483 // write height
484 for ( nIndex = 0; nIndex < 4; nIndex++ )
486 aData[nIndex] = (sal_Int8)( aSize.Height % 0x100 );
487 aSize.Height /= 0x100;
489 xTempOutStream->writeBytes( aData );
491 // write garbage, it will be overwritten by the size
492 xTempOutStream->writeBytes( aData );
494 // write first bytes that was used to detect the type
495 xTempOutStream->writeBytes( aSigData );
497 // write the rest of the stream
498 ::comphelper::OStorageHelper::CopyInputToOutput( xInCacheStream, xTempOutStream );
500 // write the size of the stream
501 sal_Int64 nLength = xTempSeek->getLength() - 40;
502 if ( nLength < 0 || nLength >= 0xFFFFFFFF )
504 OSL_FAIL( "Length is not acceptable!" );
505 return;
507 for ( sal_Int32 nInd = 0; nInd < 4; nInd++ )
509 aData[nInd] = (sal_Int8)( ( (sal_uInt64) nLength ) % 0x100 );
510 nLength /= 0x100;
512 xTempSeek->seek( 36 );
513 xTempOutStream->writeBytes( aData );
515 xTempOutStream->flush();
517 xTempSeek->seek( 0 );
518 if ( xCachedSeek.is() )
519 xCachedSeek->seek( 0 );
521 else
522 throw io::IOException(); // TODO:
524 // insert the result file as replacement image
525 ::rtl::OUString aCacheName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "\002OlePres000" ));
526 if ( xNameContainer->hasByName( aCacheName ) )
527 xNameContainer->replaceByName( aCacheName, uno::makeAny( xTempFile ) );
528 else
529 xNameContainer->insertByName( aCacheName, uno::makeAny( xTempFile ) );
531 uno::Reference< embed::XTransactedObject > xTransacted( xNameContainer, uno::UNO_QUERY );
532 if ( !xTransacted.is() )
533 throw uno::RuntimeException();
535 xTransacted->commit();
538 //------------------------------------------------------
539 void OleEmbeddedObject::RemoveVisualCache_Impl( const uno::Reference< io::XStream >& xTargetStream )
540 throw ( uno::Exception )
542 OSL_ENSURE( xTargetStream.is(), "Invalid argumant!\n" );
543 if ( !xTargetStream.is() )
544 throw uno::RuntimeException();
546 uno::Sequence< uno::Any > aArgs( 2 );
547 aArgs[0] <<= xTargetStream;
548 aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
549 uno::Reference< container::XNameContainer > xNameContainer(
550 m_xFactory->createInstanceWithArguments(
551 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLESimpleStorage" )),
552 aArgs ),
553 uno::UNO_QUERY );
555 if ( !xNameContainer.is() )
556 throw uno::RuntimeException();
558 for ( sal_uInt8 nInd = 0; nInd < 10; nInd++ )
560 ::rtl::OUString aStreamName(RTL_CONSTASCII_USTRINGPARAM( "\002OlePres00" ));
561 aStreamName += ::rtl::OUString::valueOf( (sal_Int32)nInd );
562 if ( xNameContainer->hasByName( aStreamName ) )
563 xNameContainer->removeByName( aStreamName );
566 uno::Reference< embed::XTransactedObject > xTransacted( xNameContainer, uno::UNO_QUERY );
567 if ( !xTransacted.is() )
568 throw uno::RuntimeException();
570 xTransacted->commit();
573 //------------------------------------------------------
574 void OleEmbeddedObject::SetVisReplInStream( sal_Bool bExists )
576 m_bVisReplInitialized = sal_True;
577 m_bVisReplInStream = bExists;
580 //------------------------------------------------------
581 sal_Bool OleEmbeddedObject::HasVisReplInStream()
583 if ( !m_bVisReplInitialized )
585 if ( m_xCachedVisualRepresentation.is() )
586 SetVisReplInStream( sal_True );
587 else
589 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::HasVisualReplInStream, analizing" );
591 uno::Reference< io::XInputStream > xStream;
593 OSL_ENSURE( !m_pOleComponent || !m_aTempURL.isEmpty(), "The temporary file must exist if there is a component!\n" );
594 if ( !m_aTempURL.isEmpty() )
598 // open temporary file for reading
599 uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
600 m_xFactory->createInstance (
601 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) )),
602 uno::UNO_QUERY );
604 if ( !xTempAccess.is() )
605 throw uno::RuntimeException(); // TODO:
607 xStream = xTempAccess->openFileRead( m_aTempURL );
609 catch( const uno::Exception& )
613 if ( !xStream.is() )
614 xStream = m_xObjectStream->getInputStream();
616 if ( xStream.is() )
618 sal_Bool bExists = sal_False;
620 uno::Sequence< uno::Any > aArgs( 2 );
621 aArgs[0] <<= xStream;
622 aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
623 uno::Reference< container::XNameContainer > xNameContainer(
624 m_xFactory->createInstanceWithArguments(
625 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLESimpleStorage" )),
626 aArgs ),
627 uno::UNO_QUERY );
629 if ( xNameContainer.is() )
631 for ( sal_uInt8 nInd = 0; nInd < 10 && !bExists; nInd++ )
633 ::rtl::OUString aStreamName(RTL_CONSTASCII_USTRINGPARAM( "\002OlePres00" ));
634 aStreamName += ::rtl::OUString::valueOf( (sal_Int32)nInd );
637 bExists = xNameContainer->hasByName( aStreamName );
639 catch( const uno::Exception& )
644 SetVisReplInStream( bExists );
649 return m_bVisReplInStream;
652 //------------------------------------------------------
653 uno::Reference< io::XStream > OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation_Impl(
654 const uno::Reference< io::XStream >& xStream,
655 sal_Bool bAllowToRepair50 )
656 throw ()
658 uno::Reference< io::XStream > xResult;
660 if ( xStream.is() )
662 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation, retrieving" );
664 uno::Reference< container::XNameContainer > xNameContainer;
665 uno::Sequence< uno::Any > aArgs( 2 );
666 aArgs[0] <<= xStream;
667 aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
670 xNameContainer = uno::Reference< container::XNameContainer >(
671 m_xFactory->createInstanceWithArguments(
672 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLESimpleStorage" )),
673 aArgs ),
674 uno::UNO_QUERY );
676 catch( const uno::Exception& )
679 if ( xNameContainer.is() )
681 for ( sal_uInt8 nInd = 0; nInd < 10; nInd++ )
683 ::rtl::OUString aStreamName(RTL_CONSTASCII_USTRINGPARAM( "\002OlePres00" ));
684 aStreamName += ::rtl::OUString::valueOf( (sal_Int32)nInd );
685 uno::Reference< io::XStream > xCachedCopyStream;
688 if ( ( xNameContainer->getByName( aStreamName ) >>= xCachedCopyStream ) && xCachedCopyStream.is() )
690 xResult = TryToGetAcceptableFormat_Impl( xCachedCopyStream );
691 if ( xResult.is() )
692 break;
695 catch( const uno::Exception& )
698 if ( nInd == 0 )
700 // to be compatible with the old versions Ole10Native is checked after OlePress000
701 aStreamName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\001Ole10Native" ) );
704 if ( ( xNameContainer->getByName( aStreamName ) >>= xCachedCopyStream ) && xCachedCopyStream.is() )
706 xResult = TryToGetAcceptableFormat_Impl( xCachedCopyStream );
707 if ( xResult.is() )
708 break;
711 catch( const uno::Exception& )
718 if ( bAllowToRepair50 && !xResult.is() )
720 ::rtl::OUString aOrigContName( RTL_CONSTASCII_USTRINGPARAM( "Ole-Object" ) );
721 if ( xNameContainer->hasByName( aOrigContName ) )
723 uno::Reference< embed::XClassifiedObject > xClassified( xNameContainer, uno::UNO_QUERY_THROW );
724 uno::Sequence< sal_Int8 > aClassID;
725 if ( MimeConfigurationHelper::ClassIDsEqual( xClassified->getClassID(), MimeConfigurationHelper::GetSequenceClassID( SO3_OUT_CLASSID ) ) )
727 // this is an OLE object wrongly stored in 5.0 format
728 // this object must be repaired since SO7 has done it
730 uno::Reference< io::XOutputStream > xOutputStream = xStream->getOutputStream();
731 uno::Reference< io::XTruncate > xTruncate( xOutputStream, uno::UNO_QUERY_THROW );
733 uno::Reference< io::XInputStream > xOrigInputStream;
734 if ( ( xNameContainer->getByName( aOrigContName ) >>= xOrigInputStream )
735 && xOrigInputStream.is() )
737 // the provided input stream must be based on temporary medium and must be independent
738 // from the stream the storage is based on
739 uno::Reference< io::XSeekable > xOrigSeekable( xOrigInputStream, uno::UNO_QUERY );
740 if ( xOrigSeekable.is() )
741 xOrigSeekable->seek( 0 );
743 uno::Reference< lang::XComponent > xNameContDisp( xNameContainer, uno::UNO_QUERY_THROW );
744 xNameContDisp->dispose(); // free the original stream
746 xTruncate->truncate();
747 ::comphelper::OStorageHelper::CopyInputToOutput( xOrigInputStream, xOutputStream );
748 xOutputStream->flush();
750 if ( xStream == m_xObjectStream )
752 if ( !m_aTempURL.isEmpty() )
754 // this is the own stream, so the temporary URL must be cleaned if it exists
755 KillFile_Impl( m_aTempURL, m_xFactory );
756 m_aTempURL = ::rtl::OUString();
759 #ifdef WNT
760 // retry to create the component after recovering
761 GetRidOfComponent();
765 CreateOleComponentAndLoad_Impl( NULL );
766 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
768 catch( const uno::Exception& )
770 GetRidOfComponent();
772 #endif
775 xResult = TryToRetrieveCachedVisualRepresentation_Impl( xStream, sal_False );
781 catch( const uno::Exception& )
786 return xResult;
789 //------------------------------------------------------
790 void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
791 const uno::Reference< io::XStream >& xNewObjectStream,
792 const ::rtl::OUString& aNewName )
794 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
796 OSL_ENSURE( xNewObjectStream == m_xObjectStream, "The streams must be the same!\n" );
797 return;
800 try {
801 uno::Reference< lang::XComponent > xComponent( m_xObjectStream, uno::UNO_QUERY );
802 OSL_ENSURE( !m_xObjectStream.is() || xComponent.is(), "Wrong stream implementation!" );
803 if ( xComponent.is() )
804 xComponent->dispose();
806 catch ( const uno::Exception& )
810 m_xObjectStream = xNewObjectStream;
811 m_xParentStorage = xNewParentStorage;
812 m_aEntryName = aNewName;
815 //------------------------------------------------------
816 void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
817 const ::rtl::OUString& aNewName )
819 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
820 return;
822 sal_Int32 nStreamMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
824 uno::Reference< io::XStream > xNewOwnStream = xNewParentStorage->openStreamElement( aNewName, nStreamMode );
825 OSL_ENSURE( xNewOwnStream.is(), "The method can not return empty reference!" );
827 SwitchOwnPersistence( xNewParentStorage, xNewOwnStream, aNewName );
830 #ifdef WNT
831 //----------------------------------------------
832 sal_Bool OleEmbeddedObject::SaveObject_Impl()
834 sal_Bool bResult = sal_False;
836 if ( m_xClientSite.is() )
840 m_xClientSite->saveObject();
841 bResult = sal_True;
843 catch( const uno::Exception& )
848 return bResult;
851 //----------------------------------------------
852 sal_Bool OleEmbeddedObject::OnShowWindow_Impl( sal_Bool bShow )
854 ::osl::ResettableMutexGuard aGuard( m_aMutex );
856 sal_Bool bResult = sal_False;
858 OSL_ENSURE( m_nObjectState != -1, "The object has no persistence!\n" );
859 OSL_ENSURE( m_nObjectState != embed::EmbedStates::LOADED, "The object get OnShowWindow in loaded state!\n" );
860 if ( m_nObjectState == -1 || m_nObjectState == embed::EmbedStates::LOADED )
861 return sal_False;
863 // the object is either activated or deactivated
864 sal_Int32 nOldState = m_nObjectState;
865 if ( bShow && m_nObjectState == embed::EmbedStates::RUNNING )
867 m_nObjectState = embed::EmbedStates::ACTIVE;
868 m_aVerbExecutionController.ObjectIsActive();
870 aGuard.clear();
871 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
873 else if ( !bShow && m_nObjectState == embed::EmbedStates::ACTIVE )
875 m_nObjectState = embed::EmbedStates::RUNNING;
876 aGuard.clear();
877 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
880 if ( m_xClientSite.is() )
884 m_xClientSite->visibilityChanged( bShow );
885 bResult = sal_True;
887 catch( const uno::Exception& )
892 return bResult;
895 //------------------------------------------------------
896 void OleEmbeddedObject::OnIconChanged_Impl()
898 // TODO/LATER: currently this notification seems to be impossible
899 // MakeEventListenerNotification_Impl( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "OnIconChanged" )) );
902 //------------------------------------------------------
903 void OleEmbeddedObject::OnViewChanged_Impl()
905 if ( m_bDisposed )
906 throw lang::DisposedException();
908 // For performance reasons the notification currently is ignored, STAMPIT object is the exception,
909 // it can never be active and never call SaveObject, so it is the only way to detect that it is changed
911 // ==== the STAMPIT related solution =============================
912 // the following variable is used to detect whether the object was modified during verb execution
913 m_aVerbExecutionController.ModificationNotificationIsDone();
915 // The following things are controlled by VerbExecutionController:
916 // - if the verb execution is in progress and the view is changed the object will be stored
917 // after the execution, so there is no need to send the notification.
918 // - the STAMPIT object can never be active.
919 if ( m_aVerbExecutionController.CanDoNotification()
920 && m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE )
922 OSL_ENSURE( MimeConfigurationHelper::ClassIDsEqual( m_aClassID, MimeConfigurationHelper::GetSequenceClassID( 0x852ee1c9, 0x9058, 0x44ba, 0x8c,0x6c,0x0c,0x5f,0xc6,0x6b,0xdb,0x8d ) )
923 || MimeConfigurationHelper::ClassIDsEqual( m_aClassID, MimeConfigurationHelper::GetSequenceClassID( 0xcf1b4491, 0xbea3, 0x4c9f, 0xa7,0x0f,0x22,0x1b,0x1e,0xca,0xef,0x3e ) ),
924 "Expected to be triggered for STAMPIT only! Please contact developers!\n" );
926 // The view is changed while the object is in running state, save the new object
927 m_xCachedVisualRepresentation = uno::Reference< io::XStream >();
928 SaveObject_Impl();
929 MakeEventListenerNotification_Impl( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" )) );
931 // ===============================================================
934 //------------------------------------------------------
935 void OleEmbeddedObject::OnClosed_Impl()
937 if ( m_bDisposed )
938 throw lang::DisposedException();
940 if ( m_nObjectState != embed::EmbedStates::LOADED )
942 sal_Int32 nOldState = m_nObjectState;
943 m_nObjectState = embed::EmbedStates::LOADED;
944 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
948 //------------------------------------------------------
949 ::rtl::OUString OleEmbeddedObject::CreateTempURLEmpty_Impl()
951 OSL_ENSURE( m_aTempURL.isEmpty(), "The object has already the temporary file!" );
952 m_aTempURL = GetNewTempFileURL_Impl( m_xFactory );
954 return m_aTempURL;
957 //------------------------------------------------------
958 ::rtl::OUString OleEmbeddedObject::GetTempURL_Impl()
960 if ( m_aTempURL.isEmpty() )
962 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::GetTempURL_Impl, tempfile creation" );
964 // if there is no temporary file, it will be created from the own entry
965 uno::Reference< embed::XOptimizedStorage > xOptParStorage( m_xParentStorage, uno::UNO_QUERY );
966 if ( xOptParStorage.is() )
968 m_aTempURL = GetNewFilledTempFile_Impl( xOptParStorage, m_aEntryName, m_xFactory );
970 else if ( m_xObjectStream.is() )
972 // load object from the stream
973 uno::Reference< io::XInputStream > xInStream = m_xObjectStream->getInputStream();
974 if ( !xInStream.is() )
975 throw io::IOException(); // TODO: access denied
977 m_aTempURL = GetNewFilledTempFile_Impl( xInStream, m_xFactory );
981 return m_aTempURL;
984 //------------------------------------------------------
985 void OleEmbeddedObject::CreateOleComponent_Impl( OleComponent* pOleComponent )
987 if ( !m_pOleComponent )
989 m_pOleComponent = pOleComponent ? pOleComponent : new OleComponent( m_xFactory, this );
990 m_pOleComponent->acquire(); // TODO: needs holder?
992 if ( !m_xClosePreventer.is() )
993 m_xClosePreventer = uno::Reference< util::XCloseListener >(
994 static_cast< ::cppu::OWeakObject* >( new OClosePreventer ),
995 uno::UNO_QUERY );
997 m_pOleComponent->addCloseListener( m_xClosePreventer );
1001 //------------------------------------------------------
1002 void OleEmbeddedObject::CreateOleComponentAndLoad_Impl( OleComponent* pOleComponent )
1004 if ( !m_pOleComponent )
1006 if ( !m_xObjectStream.is() )
1007 throw uno::RuntimeException();
1009 CreateOleComponent_Impl( pOleComponent );
1011 // after the loading the object can appear as a link
1012 // will be detected later by olecomponent
1014 GetTempURL_Impl();
1015 if ( m_aTempURL.isEmpty() )
1016 throw uno::RuntimeException(); // TODO
1018 m_pOleComponent->LoadEmbeddedObject( m_aTempURL );
1022 //------------------------------------------------------
1023 void OleEmbeddedObject::CreateOleComponentFromClipboard_Impl( OleComponent* pOleComponent )
1025 if ( !m_pOleComponent )
1027 if ( !m_xObjectStream.is() )
1028 throw uno::RuntimeException();
1030 CreateOleComponent_Impl( pOleComponent );
1032 // after the loading the object can appear as a link
1033 // will be detected later by olecomponent
1034 m_pOleComponent->CreateObjectFromClipboard();
1038 //------------------------------------------------------
1039 uno::Reference< io::XOutputStream > OleEmbeddedObject::GetStreamForSaving()
1041 if ( !m_xObjectStream.is() )
1042 throw uno::RuntimeException(); //TODO:
1044 uno::Reference< io::XOutputStream > xOutStream = m_xObjectStream->getOutputStream();
1045 if ( !xOutStream.is() )
1046 throw io::IOException(); //TODO: access denied
1048 uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY );
1049 if ( !xTruncate.is() )
1050 throw uno::RuntimeException(); //TODO:
1052 xTruncate->truncate();
1054 return xOutStream;
1057 //----------------------------------------------
1058 void OleEmbeddedObject::StoreObjectToStream( uno::Reference< io::XOutputStream > xOutStream )
1059 throw ( uno::Exception )
1061 // this method should be used only on windows
1062 if ( m_pOleComponent )
1063 m_pOleComponent->StoreOwnTmpIfNecessary();
1065 // now all the changes should be in temporary location
1066 if ( m_aTempURL.isEmpty() )
1067 throw uno::RuntimeException();
1069 // open temporary file for reading
1070 uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
1071 m_xFactory->createInstance (
1072 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) )),
1073 uno::UNO_QUERY );
1075 if ( !xTempAccess.is() )
1076 throw uno::RuntimeException(); // TODO:
1078 uno::Reference< io::XInputStream > xTempInStream = xTempAccess->openFileRead( m_aTempURL );
1079 OSL_ENSURE( xTempInStream.is(), "The object's temporary file can not be reopened for reading!\n" );
1081 // TODO: use bStoreVisReplace
1083 if ( xTempInStream.is() )
1085 // write all the contents to XOutStream
1086 uno::Reference< io::XTruncate > xTrunc( xOutStream, uno::UNO_QUERY );
1087 if ( !xTrunc.is() )
1088 throw uno::RuntimeException(); //TODO:
1090 xTrunc->truncate();
1092 ::comphelper::OStorageHelper::CopyInputToOutput( xTempInStream, xOutStream );
1094 else
1095 throw io::IOException(); // TODO:
1097 // TODO: should the view replacement be in the stream ???
1098 // probably it must be specified on storing
1100 #endif
1101 //------------------------------------------------------
1102 void OleEmbeddedObject::StoreToLocation_Impl(
1103 const uno::Reference< embed::XStorage >& xStorage,
1104 const ::rtl::OUString& sEntName,
1105 const uno::Sequence< beans::PropertyValue >& lObjArgs,
1106 sal_Bool bSaveAs )
1107 throw ( uno::Exception )
1109 // TODO: use lObjArgs
1110 // TODO: exchange StoreVisualReplacement by SO file format version?
1112 if ( m_nObjectState == -1 )
1114 // the object is still not loaded
1115 throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Can't store object without persistence!\n" )),
1116 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1119 if ( m_bWaitSaveCompleted )
1120 throw embed::WrongStateException(
1121 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object waits for saveCompleted() call!\n" )),
1122 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1124 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStream.is(), "The object has no valid persistence!\n" );
1126 sal_Bool bVisReplIsStored = sal_False;
1128 sal_Bool bTryOptimization = sal_False;
1129 sal_Bool bStoreVis = m_bStoreVisRepl;
1130 uno::Reference< io::XStream > xCachedVisualRepresentation;
1131 for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1133 if ( lObjArgs[nInd].Name == "StoreVisualReplacement" )
1134 lObjArgs[nInd].Value >>= bStoreVis;
1135 else if ( lObjArgs[nInd].Name == "VisualReplacement" )
1136 lObjArgs[nInd].Value >>= xCachedVisualRepresentation;
1137 else if ( lObjArgs[nInd].Name == "CanTryOptimization" )
1138 lObjArgs[nInd].Value >>= bTryOptimization;
1141 // ignore visual representation provided from outside if it should not be stored
1142 if ( !bStoreVis )
1143 xCachedVisualRepresentation = uno::Reference< io::XStream >();
1145 if ( bStoreVis && !HasVisReplInStream() && !xCachedVisualRepresentation.is() )
1146 throw io::IOException(); // TODO: there is no cached visual representation and nothing is provided from outside
1148 // if the representation is provided from outside it should be copied to a local stream
1149 sal_Bool bNeedLocalCache = xCachedVisualRepresentation.is();
1151 uno::Reference< io::XStream > xTargetStream;
1153 sal_Bool bStoreLoaded = sal_False;
1154 if ( m_nObjectState == embed::EmbedStates::LOADED
1155 #ifdef WNT
1156 // if the object was NOT modified after storing it can be just copied
1157 // as if it was in loaded state
1158 || ( m_pOleComponent && !m_pOleComponent->IsDirty() )
1159 #endif
1162 sal_Bool bOptimizedCopyingDone = sal_False;
1164 if ( bTryOptimization && bStoreVis == HasVisReplInStream() )
1168 uno::Reference< embed::XOptimizedStorage > xSourceOptStor( m_xParentStorage, uno::UNO_QUERY_THROW );
1169 uno::Reference< embed::XOptimizedStorage > xTargetOptStor( xStorage, uno::UNO_QUERY_THROW );
1170 xSourceOptStor->copyElementDirectlyTo( m_aEntryName, xTargetOptStor, sEntName );
1171 bOptimizedCopyingDone = sal_True;
1173 catch( const uno::Exception& )
1178 if ( !bOptimizedCopyingDone )
1180 // if optimized copying fails a normal one should be tried
1181 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
1184 // the locally retrieved representation is always preferable
1185 // since the object is in loaded state the representation is unchanged
1186 if ( m_xCachedVisualRepresentation.is() )
1188 xCachedVisualRepresentation = m_xCachedVisualRepresentation;
1189 bNeedLocalCache = sal_False;
1192 bVisReplIsStored = HasVisReplInStream();
1193 bStoreLoaded = sal_True;
1195 #ifdef WNT
1196 else if ( m_pOleComponent )
1198 xTargetStream =
1199 xStorage->openStreamElement( sEntName, embed::ElementModes::READWRITE );
1200 if ( !xTargetStream.is() )
1201 throw io::IOException(); //TODO: access denied
1203 SetStreamMediaType_Impl( xTargetStream, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ));
1204 uno::Reference< io::XOutputStream > xOutStream = xTargetStream->getOutputStream();
1205 if ( !xOutStream.is() )
1206 throw io::IOException(); //TODO: access denied
1208 StoreObjectToStream( xOutStream );
1209 bVisReplIsStored = sal_True;
1211 if ( bSaveAs )
1213 // no need to do it on StoreTo since in this case the replacement is in the stream
1214 // and there is no need to cache it even if it is thrown away because the object
1215 // is not changed by StoreTo action
1217 uno::Reference< io::XStream > xTmpCVRepresentation =
1218 TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
1220 // the locally retrieved representation is always preferable
1221 if ( xTmpCVRepresentation.is() )
1223 xCachedVisualRepresentation = xTmpCVRepresentation;
1224 bNeedLocalCache = sal_False;
1228 #endif
1229 else
1231 throw io::IOException(); // TODO
1234 if ( !xTargetStream.is() )
1236 xTargetStream =
1237 xStorage->openStreamElement( sEntName, embed::ElementModes::READWRITE );
1238 if ( !xTargetStream.is() )
1239 throw io::IOException(); //TODO: access denied
1242 LetCommonStoragePassBeUsed_Impl( xTargetStream );
1244 if ( bStoreVis != bVisReplIsStored )
1246 if ( bStoreVis )
1248 if ( !xCachedVisualRepresentation.is() )
1249 xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
1251 OSL_ENSURE( xCachedVisualRepresentation.is(), "No representation is available!" );
1253 // the following copying will be done in case it is SaveAs anyway
1254 // if it is not SaveAs the seekable access is not required currently
1255 // TODO/LATER: may be required in future
1256 if ( bSaveAs )
1258 uno::Reference< io::XSeekable > xCachedSeek( xCachedVisualRepresentation, uno::UNO_QUERY );
1259 if ( !xCachedSeek.is() )
1261 xCachedVisualRepresentation
1262 = GetNewFilledTempStream_Impl( xCachedVisualRepresentation->getInputStream() );
1263 bNeedLocalCache = sal_False;
1267 InsertVisualCache_Impl( xTargetStream, xCachedVisualRepresentation );
1269 else
1271 // the removed representation could be cached by this method
1272 if ( !xCachedVisualRepresentation.is() )
1273 xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
1275 RemoveVisualCache_Impl( xTargetStream );
1279 if ( bSaveAs )
1281 m_bWaitSaveCompleted = sal_True;
1282 m_xNewObjectStream = xTargetStream;
1283 m_xNewParentStorage = xStorage;
1284 m_aNewEntryName = sEntName;
1285 m_bNewVisReplInStream = bStoreVis;
1286 m_bStoreLoaded = bStoreLoaded;
1288 if ( xCachedVisualRepresentation.is() )
1290 if ( bNeedLocalCache )
1291 m_xNewCachedVisRepl = GetNewFilledTempStream_Impl( xCachedVisualRepresentation->getInputStream() );
1292 else
1293 m_xNewCachedVisRepl = xCachedVisualRepresentation;
1296 // TODO: register listeners for storages above, in case they are disposed
1297 // an exception will be thrown on saveCompleted( true )
1299 else
1301 uno::Reference< lang::XComponent > xComp( xTargetStream, uno::UNO_QUERY );
1302 if ( xComp.is() )
1304 try {
1305 xComp->dispose();
1306 } catch( const uno::Exception& )
1313 //------------------------------------------------------
1314 void SAL_CALL OleEmbeddedObject::setPersistentEntry(
1315 const uno::Reference< embed::XStorage >& xStorage,
1316 const ::rtl::OUString& sEntName,
1317 sal_Int32 nEntryConnectionMode,
1318 const uno::Sequence< beans::PropertyValue >& lArguments,
1319 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1320 throw ( lang::IllegalArgumentException,
1321 embed::WrongStateException,
1322 io::IOException,
1323 uno::Exception,
1324 uno::RuntimeException )
1326 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::setPersistentEntry" );
1328 // begin wrapping related part ====================
1329 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1330 if ( xWrappedObject.is() )
1332 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1333 xWrappedObject->setPersistentEntry( xStorage, sEntName, nEntryConnectionMode, lArguments, lObjArgs );
1334 return;
1336 // end wrapping related part ====================
1338 // TODO: use lObjArgs
1340 // the type of the object must be already set
1341 // a kind of typedetection should be done in the factory;
1342 // the only exception is object initialized from a stream,
1343 // the class ID will be detected from the stream
1345 ::osl::MutexGuard aGuard( m_aMutex );
1346 if ( m_bDisposed )
1347 throw lang::DisposedException(); // TODO
1349 if ( !xStorage.is() )
1350 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parent storage is provided!\n" )),
1351 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1352 1 );
1354 if ( sEntName.isEmpty() )
1355 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty element name is provided!\n" )),
1356 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1357 2 );
1359 // May be LOADED should be forbidden here ???
1360 if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1361 && ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) )
1363 // if the object is not loaded
1364 // it can not get persistant representation without initialization
1366 // if the object is loaded
1367 // it can switch persistant representation only without initialization
1369 throw embed::WrongStateException(
1370 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Can't change persistant representation of activated object!\n" )),
1371 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1374 if ( m_bWaitSaveCompleted )
1376 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1377 saveCompleted( ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) ) );
1378 else
1379 throw embed::WrongStateException(
1380 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object waits for saveCompleted() call!\n" )),
1381 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1384 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
1385 if ( !xNameAccess.is() )
1386 throw uno::RuntimeException(); //TODO
1388 // detect entry existence
1389 sal_Bool bElExists = xNameAccess->hasByName( sEntName );
1391 m_bReadOnly = sal_False;
1392 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1393 if ( lArguments[nInd].Name == "ReadOnly" )
1394 lArguments[nInd].Value >>= m_bReadOnly;
1396 #ifdef WNT
1397 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
1398 #endif
1400 SwitchOwnPersistence( xStorage, sEntName );
1402 for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1403 if ( lObjArgs[nInd].Name == "StoreVisualReplacement" )
1404 lObjArgs[nInd].Value >>= m_bStoreVisRepl;
1406 #ifdef WNT
1407 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT )
1409 if ( m_bFromClipboard )
1411 // the object should be initialized from clipboard
1412 // inpossibility to initialize the object means error here
1413 CreateOleComponentFromClipboard_Impl( NULL );
1414 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
1415 m_pOleComponent->RunObject();
1416 m_nObjectState = embed::EmbedStates::RUNNING;
1418 else if ( bElExists )
1420 // load object from the stream
1421 // after the loading the object can appear as a link
1422 // will be detected by olecomponent
1425 CreateOleComponentAndLoad_Impl( NULL );
1426 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
1428 catch( const uno::Exception& )
1430 // TODO/LATER: detect classID of the object if possible
1431 // means that the object inprocess server could not be successfuly instantiated
1432 GetRidOfComponent();
1435 m_nObjectState = embed::EmbedStates::LOADED;
1437 else
1439 // create a new object
1440 CreateOleComponent_Impl();
1441 m_pOleComponent->CreateNewEmbeddedObject( m_aClassID );
1442 m_pOleComponent->RunObject();
1443 m_nObjectState = embed::EmbedStates::RUNNING;
1446 else
1448 if ( ( nStorageMode & embed::ElementModes::READWRITE ) != embed::ElementModes::READWRITE )
1449 throw io::IOException();
1451 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1453 // the document just already changed its stream to store to;
1454 // the links to OLE documents switch their persistence in the same way
1455 // as normal embedded objects
1457 else if ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT )
1459 // create a new object, that will be stored in specified stream
1460 CreateOleComponent_Impl();
1462 m_pOleComponent->CreateNewEmbeddedObject( m_aClassID );
1463 m_pOleComponent->RunObject();
1464 m_nObjectState = embed::EmbedStates::RUNNING;
1466 else if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
1468 // use URL ( may be content or stream later ) from MediaDescriptor to initialize object
1469 ::rtl::OUString aURL;
1470 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1471 if ( lArguments[nInd].Name == "URL" )
1472 lArguments[nInd].Value >>= aURL;
1474 if ( aURL.isEmpty() )
1475 throw lang::IllegalArgumentException(
1476 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty URL is provided in the media descriptor!\n" )),
1477 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1478 4 );
1480 CreateOleComponent_Impl();
1482 // TODO: the m_bIsLink value must be set already
1483 if ( !m_bIsLink )
1484 m_pOleComponent->CreateObjectFromFile( aURL );
1485 else
1486 m_pOleComponent->CreateLinkFromFile( aURL );
1488 m_pOleComponent->RunObject();
1489 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
1491 m_nObjectState = embed::EmbedStates::RUNNING;
1493 //else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT )
1495 //TODO:
1497 else
1498 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Wrong connection mode is provided!\n" )),
1499 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1500 3 );
1502 #else
1503 // On unix the ole object can not do anything except storing itself somewere
1504 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT && bElExists )
1506 // TODO/LATER: detect classID of the object
1507 // can be a real problem for the links
1509 m_nObjectState = embed::EmbedStates::LOADED;
1511 else if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1513 // do nothing, the object has already switched it's persistence
1515 else
1516 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Wrong connection mode is provided!\n" )),
1517 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1518 3 );
1520 #endif
1523 //------------------------------------------------------
1524 void SAL_CALL OleEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage,
1525 const ::rtl::OUString& sEntName,
1526 const uno::Sequence< beans::PropertyValue >& lArguments,
1527 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1528 throw ( lang::IllegalArgumentException,
1529 embed::WrongStateException,
1530 io::IOException,
1531 uno::Exception,
1532 uno::RuntimeException )
1534 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::storeToEntry" );
1536 // begin wrapping related part ====================
1537 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1538 if ( xWrappedObject.is() )
1540 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1541 xWrappedObject->storeToEntry( xStorage, sEntName, lArguments, lObjArgs );
1542 return;
1544 // end wrapping related part ====================
1546 ::osl::MutexGuard aGuard( m_aMutex );
1547 if ( m_bDisposed )
1548 throw lang::DisposedException(); // TODO
1550 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
1552 StoreToLocation_Impl( xStorage, sEntName, lObjArgs, sal_False );
1554 // TODO: should the listener notification be done?
1557 //------------------------------------------------------
1558 void SAL_CALL OleEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage,
1559 const ::rtl::OUString& sEntName,
1560 const uno::Sequence< beans::PropertyValue >& lArguments,
1561 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1562 throw ( lang::IllegalArgumentException,
1563 embed::WrongStateException,
1564 io::IOException,
1565 uno::Exception,
1566 uno::RuntimeException )
1568 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::storeAsEntry" );
1570 // begin wrapping related part ====================
1571 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1572 if ( xWrappedObject.is() )
1574 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1575 xWrappedObject->storeAsEntry( xStorage, sEntName, lArguments, lObjArgs );
1576 return;
1578 // end wrapping related part ====================
1580 ::osl::MutexGuard aGuard( m_aMutex );
1581 if ( m_bDisposed )
1582 throw lang::DisposedException(); // TODO
1584 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
1586 StoreToLocation_Impl( xStorage, sEntName, lObjArgs, sal_True );
1588 // TODO: should the listener notification be done here or in saveCompleted?
1591 //------------------------------------------------------
1592 void SAL_CALL OleEmbeddedObject::saveCompleted( sal_Bool bUseNew )
1593 throw ( embed::WrongStateException,
1594 uno::Exception,
1595 uno::RuntimeException )
1597 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::saveCompleted" );
1599 // begin wrapping related part ====================
1600 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1601 if ( xWrappedObject.is() )
1603 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1604 xWrappedObject->saveCompleted( bUseNew );
1605 return;
1607 // end wrapping related part ====================
1609 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1610 if ( m_bDisposed )
1611 throw lang::DisposedException(); // TODO
1613 if ( m_nObjectState == -1 )
1615 // the object is still not loaded
1616 throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Can't store object without persistence!\n" )),
1617 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1620 // it is allowed to call saveCompleted( false ) for nonstored objects
1621 if ( !m_bWaitSaveCompleted && !bUseNew )
1622 return;
1624 OSL_ENSURE( m_bWaitSaveCompleted, "Unexpected saveCompleted() call!\n" );
1625 if ( !m_bWaitSaveCompleted )
1626 throw io::IOException(); // TODO: illegal call
1628 OSL_ENSURE( m_xNewObjectStream.is() && m_xNewParentStorage.is() , "Internal object information is broken!\n" );
1629 if ( !m_xNewObjectStream.is() || !m_xNewParentStorage.is() )
1630 throw uno::RuntimeException(); // TODO: broken internal information
1632 if ( bUseNew )
1634 SwitchOwnPersistence( m_xNewParentStorage, m_xNewObjectStream, m_aNewEntryName );
1635 m_bStoreVisRepl = m_bNewVisReplInStream;
1636 SetVisReplInStream( m_bNewVisReplInStream );
1637 m_xCachedVisualRepresentation = m_xNewCachedVisRepl;
1639 else
1641 // close remembered stream
1642 try {
1643 uno::Reference< lang::XComponent > xComponent( m_xNewObjectStream, uno::UNO_QUERY );
1644 OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" );
1645 if ( xComponent.is() )
1646 xComponent->dispose();
1648 catch ( const uno::Exception& )
1653 sal_Bool bStoreLoaded = m_bStoreLoaded;
1655 m_xNewObjectStream = uno::Reference< io::XStream >();
1656 m_xNewParentStorage = uno::Reference< embed::XStorage >();
1657 m_aNewEntryName = ::rtl::OUString();
1658 m_bWaitSaveCompleted = sal_False;
1659 m_bNewVisReplInStream = sal_False;
1660 m_xNewCachedVisRepl = uno::Reference< io::XStream >();
1661 m_bStoreLoaded = sal_False;
1663 if ( bUseNew && m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded
1664 && m_nObjectState != embed::EmbedStates::LOADED )
1666 // the object replacement image should be updated, so the cached size as well
1667 m_bHasCachedSize = sal_False;
1670 // the call will cache the size in case of success
1671 // probably it might need to be done earlier, while the object is in active state
1672 getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1674 catch( const uno::Exception& )
1678 aGuard.clear();
1679 if ( bUseNew )
1681 MakeEventListenerNotification_Impl( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "OnSaveAsDone" ) ));
1683 // the object can be changed only on windows
1684 // the notification should be done only if the object is not in loaded state
1685 if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
1687 MakeEventListenerNotification_Impl( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" ) ));
1692 //------------------------------------------------------
1693 sal_Bool SAL_CALL OleEmbeddedObject::hasEntry()
1694 throw ( embed::WrongStateException,
1695 uno::RuntimeException )
1697 // begin wrapping related part ====================
1698 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1699 if ( xWrappedObject.is() )
1701 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1702 return xWrappedObject->hasEntry();
1704 // end wrapping related part ====================
1706 ::osl::MutexGuard aGuard( m_aMutex );
1707 if ( m_bDisposed )
1708 throw lang::DisposedException(); // TODO
1710 if ( m_bWaitSaveCompleted )
1711 throw embed::WrongStateException(
1712 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object waits for saveCompleted() call!\n" )),
1713 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1715 if ( m_xObjectStream.is() )
1716 return sal_True;
1718 return sal_False;
1721 //------------------------------------------------------
1722 ::rtl::OUString SAL_CALL OleEmbeddedObject::getEntryName()
1723 throw ( embed::WrongStateException,
1724 uno::RuntimeException )
1726 // begin wrapping related part ====================
1727 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1728 if ( xWrappedObject.is() )
1730 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1731 return xWrappedObject->getEntryName();
1733 // end wrapping related part ====================
1735 ::osl::MutexGuard aGuard( m_aMutex );
1736 if ( m_bDisposed )
1737 throw lang::DisposedException(); // TODO
1739 if ( m_nObjectState == -1 )
1741 // the object is still not loaded
1742 throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object persistence is not initialized!\n" )),
1743 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1746 if ( m_bWaitSaveCompleted )
1747 throw embed::WrongStateException(
1748 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object waits for saveCompleted() call!\n" )),
1749 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1751 return m_aEntryName;
1755 //------------------------------------------------------
1756 void SAL_CALL OleEmbeddedObject::storeOwn()
1757 throw ( embed::WrongStateException,
1758 io::IOException,
1759 uno::Exception,
1760 uno::RuntimeException )
1762 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::storeOwn" );
1764 // begin wrapping related part ====================
1765 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1766 if ( xWrappedObject.is() )
1768 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1769 xWrappedObject->storeOwn();
1770 return;
1772 // end wrapping related part ====================
1774 // during switching from Activated to Running and from Running to Loaded states the object will
1775 // ask container to store the object, the container has to make decision
1776 // to do so or not
1778 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1779 if ( m_bDisposed )
1780 throw lang::DisposedException(); // TODO
1782 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
1784 if ( m_nObjectState == -1 )
1786 // the object is still not loaded
1787 throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Can't store object without persistence!\n" )),
1788 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1791 if ( m_bWaitSaveCompleted )
1792 throw embed::WrongStateException(
1793 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object waits for saveCompleted() call!\n" )),
1794 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1796 if ( m_bReadOnly )
1797 throw io::IOException(); // TODO: access denied
1799 LetCommonStoragePassBeUsed_Impl( m_xObjectStream );
1801 sal_Bool bStoreLoaded = sal_True;
1803 #ifdef WNT
1804 if ( m_nObjectState != embed::EmbedStates::LOADED && m_pOleComponent && m_pOleComponent->IsDirty() )
1806 bStoreLoaded = sal_False;
1808 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStream.is(), "The object has no valid persistence!\n" );
1810 if ( !m_xObjectStream.is() )
1811 throw io::IOException(); //TODO: access denied
1813 SetStreamMediaType_Impl( m_xObjectStream, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ));
1814 uno::Reference< io::XOutputStream > xOutStream = m_xObjectStream->getOutputStream();
1815 if ( !xOutStream.is() )
1816 throw io::IOException(); //TODO: access denied
1818 // TODO: does this work for links too?
1819 StoreObjectToStream( GetStreamForSaving() );
1821 // the replacement is changed probably, and it must be in the object stream
1822 if ( !m_pOleComponent->IsWorkaroundActive() )
1823 m_xCachedVisualRepresentation = uno::Reference< io::XStream >();
1824 SetVisReplInStream( sal_True );
1826 #endif
1828 if ( m_bStoreVisRepl != HasVisReplInStream() )
1830 if ( m_bStoreVisRepl )
1832 // the m_xCachedVisualRepresentation must be set or it should be already stored
1833 if ( m_xCachedVisualRepresentation.is() )
1834 InsertVisualCache_Impl( m_xObjectStream, m_xCachedVisualRepresentation );
1835 else
1837 m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream );
1838 OSL_ENSURE( m_xCachedVisualRepresentation.is(), "No representation is available!" );
1841 else
1843 if ( !m_xCachedVisualRepresentation.is() )
1844 m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream );
1845 RemoveVisualCache_Impl( m_xObjectStream );
1848 SetVisReplInStream( m_bStoreVisRepl );
1851 if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
1853 // the object replacement image should be updated, so the cached size as well
1854 m_bHasCachedSize = sal_False;
1857 // the call will cache the size in case of success
1858 // probably it might need to be done earlier, while the object is in active state
1859 getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1861 catch( const uno::Exception& )
1865 aGuard.clear();
1867 MakeEventListenerNotification_Impl( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "OnSaveDone" ) ));
1869 // the object can be changed only on Windows
1870 // the notification should be done only if the object is not in loaded state
1871 if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
1872 MakeEventListenerNotification_Impl( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "OnVisAreaChanged" ) ));
1875 //------------------------------------------------------
1876 sal_Bool SAL_CALL OleEmbeddedObject::isReadonly()
1877 throw ( embed::WrongStateException,
1878 uno::RuntimeException )
1880 // begin wrapping related part ====================
1881 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1882 if ( xWrappedObject.is() )
1884 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1885 return xWrappedObject->isReadonly();
1887 // end wrapping related part ====================
1889 ::osl::MutexGuard aGuard( m_aMutex );
1890 if ( m_bDisposed )
1891 throw lang::DisposedException(); // TODO
1893 if ( m_nObjectState == -1 )
1895 // the object is still not loaded
1896 throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object persistence is not initialized!\n" )),
1897 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1900 if ( m_bWaitSaveCompleted )
1901 throw embed::WrongStateException(
1902 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object waits for saveCompleted() call!\n" )),
1903 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1905 return m_bReadOnly;
1908 //------------------------------------------------------
1909 void SAL_CALL OleEmbeddedObject::reload(
1910 const uno::Sequence< beans::PropertyValue >& lArguments,
1911 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1912 throw ( lang::IllegalArgumentException,
1913 embed::WrongStateException,
1914 io::IOException,
1915 uno::Exception,
1916 uno::RuntimeException )
1918 // begin wrapping related part ====================
1919 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1920 if ( xWrappedObject.is() )
1922 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1923 xWrappedObject->reload( lArguments, lObjArgs );
1924 return;
1926 // end wrapping related part ====================
1928 // TODO: use lObjArgs
1930 ::osl::MutexGuard aGuard( m_aMutex );
1931 if ( m_bDisposed )
1932 throw lang::DisposedException(); // TODO
1934 if ( m_nObjectState == -1 )
1936 // the object is still not loaded
1937 throw embed::WrongStateException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object persistence is not initialized!\n" )),
1938 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1941 if ( m_bWaitSaveCompleted )
1942 throw embed::WrongStateException(
1943 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object waits for saveCompleted() call!\n" )),
1944 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1946 // TODO:
1947 // throw away current document
1948 // load new document from current storage
1949 // use meaningfull part of lArguments
1952 //------------------------------------------------------
1953 void SAL_CALL OleEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage,
1954 const ::rtl::OUString& sEntName )
1955 throw ( lang::IllegalArgumentException,
1956 embed::WrongStateException,
1957 io::IOException,
1958 uno::Exception,
1959 uno::RuntimeException )
1961 // begin wrapping related part ====================
1962 uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1963 if ( xWrappedObject.is() )
1965 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1966 xWrappedObject->breakLink( xStorage, sEntName );
1967 return;
1969 // end wrapping related part ====================
1971 ::osl::MutexGuard aGuard( m_aMutex );
1972 if ( m_bDisposed )
1973 throw lang::DisposedException(); // TODO
1975 if ( !xStorage.is() )
1976 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parent storage is provided!\n" )),
1977 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1978 1 );
1980 if ( sEntName.isEmpty() )
1981 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty element name is provided!\n" )),
1982 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1983 2 );
1985 // TODO: The object must be at least in Running state;
1986 if ( !m_bIsLink || m_nObjectState == -1 || !m_pOleComponent )
1988 // it must be a linked initialized object
1989 throw embed::WrongStateException(
1990 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object is not a valid linked object!\n" )),
1991 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1994 if ( m_bReadOnly )
1995 throw io::IOException(); // TODO: Access denied
1997 if ( m_bWaitSaveCompleted )
1998 throw embed::WrongStateException(
1999 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object waits for saveCompleted() call!\n" )),
2000 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
2003 #ifdef WNT
2004 if ( m_pOleComponent )
2006 // TODO: create an object based on the link
2008 // disconnect the old temporary URL
2009 ::rtl::OUString aOldTempURL = m_aTempURL;
2010 m_aTempURL = ::rtl::OUString();
2012 OleComponent* pNewOleComponent = new OleComponent( m_xFactory, this );
2013 try {
2014 pNewOleComponent->InitEmbeddedCopyOfLink( m_pOleComponent );
2016 catch ( const uno::Exception& )
2018 delete pNewOleComponent;
2019 if ( !m_aTempURL.isEmpty() )
2020 KillFile_Impl( m_aTempURL, m_xFactory );
2021 m_aTempURL = aOldTempURL;
2022 throw;
2025 try {
2026 GetRidOfComponent();
2028 catch( const uno::Exception& )
2030 delete pNewOleComponent;
2031 if ( !m_aTempURL.isEmpty() )
2032 KillFile_Impl( m_aTempURL, m_xFactory );
2033 m_aTempURL = aOldTempURL;
2034 throw;
2037 KillFile_Impl( aOldTempURL, m_xFactory );
2039 CreateOleComponent_Impl( pNewOleComponent );
2041 if ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) )
2042 SwitchOwnPersistence( xStorage, sEntName );
2044 if ( m_nObjectState != embed::EmbedStates::LOADED )
2046 // TODO: should we activate the new object if the link was activated?
2048 sal_Int32 nTargetState = m_nObjectState;
2049 m_nObjectState = embed::EmbedStates::LOADED;
2051 if ( m_nObjectState == embed::EmbedStates::RUNNING )
2052 m_pOleComponent->RunObject(); // the object already was in running state, the server must be installed
2053 else // m_nObjectState == embed::EmbedStates::ACTIVE
2055 m_pOleComponent->RunObject(); // the object already was in running state, the server must be installed
2056 m_pOleComponent->ExecuteVerb( embed::EmbedVerbs::MS_OLEVERB_OPEN );
2059 m_nObjectState = nTargetState;
2062 m_bIsLink = sal_False;
2063 m_aLinkURL = ::rtl::OUString();
2065 else
2066 #endif
2068 throw io::IOException(); //TODO:
2072 //------------------------------------------------------
2073 sal_Bool SAL_CALL OleEmbeddedObject::isLink()
2074 throw ( embed::WrongStateException,
2075 uno::RuntimeException )
2077 // begin wrapping related part ====================
2078 uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
2079 if ( xWrappedObject.is() )
2081 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2082 return xWrappedObject->isLink();
2084 // end wrapping related part ====================
2086 ::osl::MutexGuard aGuard( m_aMutex );
2087 if ( m_bDisposed )
2088 throw lang::DisposedException(); // TODO
2090 return m_bIsLink;
2093 //------------------------------------------------------
2094 ::rtl::OUString SAL_CALL OleEmbeddedObject::getLinkURL()
2095 throw ( embed::WrongStateException,
2096 uno::Exception,
2097 uno::RuntimeException )
2099 // begin wrapping related part ====================
2100 uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
2101 if ( xWrappedObject.is() )
2103 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2104 return xWrappedObject->getLinkURL();
2106 // end wrapping related part ====================
2108 ::osl::MutexGuard aGuard( m_aMutex );
2109 if ( m_bDisposed )
2110 throw lang::DisposedException(); // TODO
2112 if ( m_bWaitSaveCompleted )
2113 throw embed::WrongStateException(
2114 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object waits for saveCompleted() call!\n" )),
2115 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
2117 if ( !m_bIsLink )
2118 throw embed::WrongStateException(
2119 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "The object is not a link object!\n" )),
2120 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
2122 // TODO: probably the link URL can be retrieved from OLE
2124 return m_aLinkURL;
2127 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */