update dev300-m58
[ooovba.git] / embeddedobj / source / msole / olepersist.cxx
bloba85356e1913f2f23be79469909549aba13f70033
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: olepersist.cxx,v $
10 * $Revision: 1.39 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_embeddedobj.hxx"
34 #include <oleembobj.hxx>
35 #include <com/sun/star/embed/EmbedStates.hpp>
36 #include <com/sun/star/embed/EmbedVerbs.hpp>
37 #include <com/sun/star/embed/EntryInitModes.hpp>
38 #include <com/sun/star/embed/XStorage.hpp>
39 #include <com/sun/star/embed/XTransactedObject.hpp>
40 #include <com/sun/star/embed/ElementModes.hpp>
41 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
42 #include <com/sun/star/embed/Aspects.hpp>
43 #include <com/sun/star/embed/XOptimizedStorage.hpp>
44 #include <com/sun/star/lang/XComponent.hpp>
45 #include <com/sun/star/lang/DisposedException.hpp>
46 #include <com/sun/star/container/XNameAccess.hpp>
47 #include <com/sun/star/container/XNameContainer.hpp>
48 #include <com/sun/star/io/XSeekable.hpp>
49 #include <com/sun/star/io/XTruncate.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
53 #include <rtl/logfile.hxx>
55 #include <comphelper/storagehelper.hxx>
56 #include <comphelper/mimeconfighelper.hxx>
57 #include <comphelper/classids.hxx>
60 #include <olecomponent.hxx>
61 #include <closepreventer.hxx>
63 using namespace ::com::sun::star;
64 using namespace ::comphelper;
66 //-------------------------------------------------------------------------
67 sal_Bool KillFile_Impl( const ::rtl::OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
69 if ( !xFactory.is() )
70 return sal_False;
72 sal_Bool bRet = sal_False;
74 try
76 uno::Reference < ucb::XSimpleFileAccess > xAccess(
77 xFactory->createInstance (
78 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
79 uno::UNO_QUERY );
81 if ( xAccess.is() )
83 xAccess->kill( aURL );
84 bRet = sal_True;
87 catch( uno::Exception& )
91 return bRet;
94 //----------------------------------------------
95 ::rtl::OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
97 OSL_ENSURE( xFactory.is(), "No factory is provided!\n" );
99 ::rtl::OUString aResult;
101 uno::Reference < beans::XPropertySet > xTempFile(
102 xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
103 uno::UNO_QUERY );
105 if ( !xTempFile.is() )
106 throw uno::RuntimeException(); // TODO
108 try {
109 xTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False ) );
110 uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
111 aUrl >>= aResult;
113 catch ( uno::Exception& )
117 if ( !aResult.getLength() )
118 throw uno::RuntimeException(); // TODO: can not create tempfile
120 return aResult;
123 //-----------------------------------------------
124 ::rtl::OUString GetNewFilledTempFile_Impl( const uno::Reference< io::XInputStream >& xInStream,
125 const uno::Reference< lang::XMultiServiceFactory >& xFactory )
126 throw ( io::IOException,
127 uno::RuntimeException )
129 OSL_ENSURE( xInStream.is() && xFactory.is(), "Wrong parameters are provided!\n" );
131 ::rtl::OUString aResult = GetNewTempFileURL_Impl( xFactory );
133 if ( aResult.getLength() )
135 try {
136 uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
137 xFactory->createInstance (
138 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
139 uno::UNO_QUERY );
141 if ( !xTempAccess.is() )
142 throw uno::RuntimeException(); // TODO:
144 uno::Reference< io::XOutputStream > xTempOutStream = xTempAccess->openFileWrite( aResult );
145 if ( xTempOutStream.is() )
147 // copy stream contents to the file
148 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOutStream );
149 xTempOutStream->closeOutput();
150 xTempOutStream = uno::Reference< io::XOutputStream >();
152 else
153 throw io::IOException(); // TODO:
155 catch( packages::WrongPasswordException& )
157 KillFile_Impl( aResult, xFactory );
158 throw io::IOException(); //TODO:
160 catch( io::IOException& )
162 KillFile_Impl( aResult, xFactory );
163 throw;
165 catch( uno::RuntimeException& )
167 KillFile_Impl( aResult, xFactory );
168 throw;
170 catch( uno::Exception& )
172 KillFile_Impl( aResult, xFactory );
173 aResult = ::rtl::OUString();
177 return aResult;
179 #ifdef WNT
180 ::rtl::OUString GetNewFilledTempFile_Impl( const uno::Reference< embed::XOptimizedStorage >& xParentStorage, const ::rtl::OUString& aEntryName, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
181 throw( io::IOException, uno::RuntimeException )
183 ::rtl::OUString aResult;
187 uno::Reference < beans::XPropertySet > xTempFile(
188 xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
189 uno::UNO_QUERY );
190 uno::Reference < io::XStream > xTempStream( xTempFile, uno::UNO_QUERY_THROW );
192 xParentStorage->copyStreamElementData( aEntryName, xTempStream );
194 xTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False ) );
195 uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
196 aUrl >>= aResult;
198 catch( uno::RuntimeException& )
200 throw;
202 catch( uno::Exception& )
206 if ( !aResult.getLength() )
207 throw io::IOException();
209 return aResult;
212 //------------------------------------------------------
213 void SetStreamMediaType_Impl( const uno::Reference< io::XStream >& xStream, const ::rtl::OUString& aMediaType )
215 uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY );
216 if ( !xPropSet.is() )
217 throw uno::RuntimeException(); // TODO: all the storage streams must support XPropertySet
219 xPropSet->setPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ), uno::makeAny( aMediaType ) );
221 #endif
222 //------------------------------------------------------
223 void LetCommonStoragePassBeUsed_Impl( const uno::Reference< io::XStream >& xStream )
225 uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY );
226 if ( !xPropSet.is() )
227 throw uno::RuntimeException(); // Only StorageStreams must be provided here, they must implement the interface
229 xPropSet->setPropertyValue( ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" ),
230 uno::makeAny( (sal_Bool)sal_True ) );
232 #ifdef WNT
233 //------------------------------------------------------
234 void VerbExecutionController::StartControlExecution()
236 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
238 // the class is used to detect STAMPIT object, that can never be active
239 if ( !m_bVerbExecutionInProgress && !m_bWasEverActive )
241 m_bVerbExecutionInProgress = sal_True;
242 m_nVerbExecutionThreadIdentifier = osl_getThreadIdentifier( NULL );
243 m_bChangedOnVerbExecution = sal_False;
247 //------------------------------------------------------
248 sal_Bool VerbExecutionController::EndControlExecution_WasModified()
250 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
252 sal_Bool bResult = sal_False;
253 if ( m_bVerbExecutionInProgress && m_nVerbExecutionThreadIdentifier == osl_getThreadIdentifier( NULL ) )
255 bResult = m_bChangedOnVerbExecution;
256 m_bVerbExecutionInProgress = sal_False;
259 return bResult;
262 //------------------------------------------------------
263 void VerbExecutionController::ModificationNotificationIsDone()
265 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
267 if ( m_bVerbExecutionInProgress && osl_getThreadIdentifier( NULL ) == m_nVerbExecutionThreadIdentifier )
268 m_bChangedOnVerbExecution = sal_True;
270 #endif
271 //-----------------------------------------------
272 void VerbExecutionController::LockNotification()
274 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
275 if ( m_nNotificationLock < SAL_MAX_INT32 )
276 m_nNotificationLock++;
279 //-----------------------------------------------
280 void VerbExecutionController::UnlockNotification()
282 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
283 if ( m_nNotificationLock > 0 )
284 m_nNotificationLock--;
287 //-----------------------------------------------
288 uno::Reference< io::XStream > OleEmbeddedObject::GetNewFilledTempStream_Impl( const uno::Reference< io::XInputStream >& xInStream )
289 throw( io::IOException )
291 OSL_ENSURE( xInStream.is(), "Wrong parameter is provided!\n" );
293 uno::Reference < io::XStream > xTempFile(
294 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
295 uno::UNO_QUERY_THROW );
297 uno::Reference< io::XOutputStream > xTempOutStream = xTempFile->getOutputStream();
298 if ( xTempOutStream.is() )
300 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOutStream );
301 xTempOutStream->flush();
303 else
304 throw io::IOException(); // TODO:
306 return xTempFile;
309 //------------------------------------------------------
310 uno::Reference< io::XStream > OleEmbeddedObject::TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream )
311 throw ( uno::Exception )
313 // TODO/LATER: Actually this should be done by a centralized component ( may be a graphical filter )
314 if ( !m_xFactory.is() )
315 throw uno::RuntimeException();
317 uno::Reference< io::XInputStream > xInStream = xStream->getInputStream();
318 if ( !xInStream.is() )
319 throw uno::RuntimeException();
321 uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
322 xSeek->seek( 0 );
324 uno::Sequence< sal_Int8 > aData( 8 );
325 sal_Int32 nRead = xInStream->readBytes( aData, 8 );
326 xSeek->seek( 0 );
328 if ( ( nRead >= 2 && aData[0] == 'B' && aData[1] == 'M' )
329 || ( nRead >= 4 && aData[0] == 1 && aData[1] == 0 && aData[2] == 9 && aData[3] == 0 ) )
331 // it should be a bitmap or a Metafile
332 return xStream;
335 // sal_Bool bSetSizeToRepl = sal_False;
336 // awt::Size aSizeToSet;
338 sal_uInt32 nHeaderOffset = 0;
339 if ( ( nRead >= 8 && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1 )
340 && ( aData[4] == 2 || aData[4] == 3 || aData[4] == 14 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
342 nHeaderOffset = 40;
343 xSeek->seek( 8 );
345 // TargetDevice might be used in future, currently the cache has specified NULL
346 uno::Sequence< sal_Int8 > aHeadData( 4 );
347 nRead = xInStream->readBytes( aHeadData, 4 );
348 sal_uInt32 nLen = 0;
349 if ( nRead == 4 && aHeadData.getLength() == 4 )
350 nLen = ( ( ( (sal_uInt32)aHeadData[3] * 0x100 + (sal_uInt32)aHeadData[2] ) * 0x100 ) + (sal_uInt32)aHeadData[1] ) * 0x100 + (sal_uInt32)aHeadData[0];
351 if ( nLen > 4 )
353 xInStream->skipBytes( nLen - 4 );
354 nHeaderOffset += nLen - 4;
357 // if ( aData[4] == 3 )
358 // {
359 // try
360 // {
362 // aSizeToSet = getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
363 // aSizeToSet.Width /= 364; //2540; // let the size be in inches, as wmf requires
364 // aSizeToSet.Height /= 364; //2540; // let the size be in inches, as wmf requires
365 // bSetSizeToRepl = sal_True;
366 // }
367 // catch( uno::Exception& )
368 // {}
369 // }
371 else if ( nRead > 4 )
373 // check whether the first bytes represent the size
374 sal_uInt32 nSize = 0;
375 for ( sal_Int32 nInd = 3; nInd >= 0; nInd-- )
376 nSize = ( nSize << 8 ) + (sal_uInt8)aData[nInd];
378 if ( nSize == xSeek->getLength() - 4 )
379 nHeaderOffset = 4;
382 if ( nHeaderOffset )
384 // this is either a bitmap or a metafile clipboard format, retrieve the pure stream
385 uno::Reference < io::XStream > xResult(
386 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
387 uno::UNO_QUERY_THROW );
388 uno::Reference < io::XSeekable > xResultSeek( xResult, uno::UNO_QUERY_THROW );
389 uno::Reference < io::XOutputStream > xResultOut = xResult->getOutputStream();
390 uno::Reference < io::XInputStream > xResultIn = xResult->getInputStream();
391 if ( !xResultOut.is() || !xResultIn.is() )
392 throw uno::RuntimeException();
394 // if it is windows metafile the size must be provided
395 // the solution is not used currently
396 // if ( bSetSizeToRepl && abs( aSizeToSet.Width ) < 0xFFFF && abs( aSizeToSet.Height ) < 0xFFFF )
397 // {
398 // uno::Sequence< sal_Int8 > aHeader(22);
399 // sal_uInt8* pBuffer = (sal_uInt8*)aHeader.getArray();
401 // // write 0x9ac6cdd7L
402 // pBuffer[0] = 0xd7;
403 // pBuffer[1] = 0xcd;
404 // pBuffer[2] = 0xc6;
405 // pBuffer[3] = 0x9a;
407 // // following data seems to have no value
408 // pBuffer[4] = 0;
409 // pBuffer[5] = 0;
411 // // must be set to 0
412 // pBuffer[6] = 0;
413 // pBuffer[7] = 0;
414 // pBuffer[8] = 0;
415 // pBuffer[9] = 0;
417 // // width of the picture
418 // pBuffer[10] = abs( aSizeToSet.Width ) % 0x100;
419 // pBuffer[11] = ( abs( aSizeToSet.Width ) / 0x100 ) % 0x100;
421 // // height of the picture
422 // pBuffer[12] = abs( aSizeToSet.Height ) % 0x100;
423 // pBuffer[13] = ( abs( aSizeToSet.Height ) / 0x100 ) % 0x100;
425 // // write 2540
426 // pBuffer[14] = 0x6c; //0xec;
427 // pBuffer[15] = 0x01; //0x09;
429 // // fill with 0
430 // for ( sal_Int32 nInd = 16; nInd < 22; nInd++ )
431 // pBuffer[nInd] = 0;
433 // xResultOut->writeBytes( aHeader );
434 // }
436 xSeek->seek( nHeaderOffset ); // header size for these formats
437 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xResultOut );
438 xResultOut->closeOutput();
439 xResultSeek->seek( 0 );
440 xSeek->seek( 0 );
442 return xResult;
445 return uno::Reference< io::XStream >();
448 //------------------------------------------------------
449 void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStream >& xTargetStream,
450 const uno::Reference< io::XStream >& xCachedVisualRepresentation )
451 throw ( uno::Exception )
453 OSL_ENSURE( xTargetStream.is() && xCachedVisualRepresentation.is(), "Invalid argumants!\n" );
455 if ( !xTargetStream.is() || !xCachedVisualRepresentation.is() )
456 throw uno::RuntimeException();
458 uno::Sequence< uno::Any > aArgs( 2 );
459 aArgs[0] <<= xTargetStream;
460 aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
462 uno::Reference< container::XNameContainer > xNameContainer(
463 m_xFactory->createInstanceWithArguments(
464 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
465 aArgs ),
466 uno::UNO_QUERY );
468 if ( !xNameContainer.is() )
469 throw uno::RuntimeException();
471 uno::Reference< io::XSeekable > xCachedSeek( xCachedVisualRepresentation, uno::UNO_QUERY_THROW );
472 if ( xCachedSeek.is() )
473 xCachedSeek->seek( 0 );
475 uno::Reference < io::XStream > xTempFile(
476 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
477 uno::UNO_QUERY_THROW );
479 uno::Reference< io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY_THROW );
480 uno::Reference< io::XOutputStream > xTempOutStream = xTempFile->getOutputStream();
481 if ( xTempOutStream.is() )
483 // the OlePres stream must have additional header
484 // TODO/LATER: might need to be extended in future ( actually makes sence only for SO7 format )
485 uno::Reference< io::XInputStream > xInCacheStream = xCachedVisualRepresentation->getInputStream();
486 if ( !xInCacheStream.is() )
487 throw uno::RuntimeException();
489 // write 0xFFFFFFFF at the beginning
490 uno::Sequence< sal_Int8 > aData( 4 );
491 *( (sal_uInt32*)aData.getArray() ) = 0xFFFFFFFF;
493 xTempOutStream->writeBytes( aData );
495 // write clipboard format
496 uno::Sequence< sal_Int8 > aSigData( 2 );
497 xInCacheStream->readBytes( aSigData, 2 );
498 if ( aSigData.getLength() < 2 )
499 throw io::IOException();
501 if ( aSigData[0] == 'B' && aSigData[1] == 'M' )
503 // it's a bitmap
504 aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0;
506 else
508 // treat it as a metafile
509 aData[0] = 0x03; aData[1] = 0; aData[2] = 0; aData[3] = 0;
511 xTempOutStream->writeBytes( aData );
513 // write job related information
514 aData[0] = 0x04; aData[1] = 0; aData[2] = 0; aData[3] = 0;
515 xTempOutStream->writeBytes( aData );
517 // write aspect
518 aData[0] = 0x01; aData[1] = 0; aData[2] = 0; aData[3] = 0;
519 xTempOutStream->writeBytes( aData );
521 // write l-index
522 *( (sal_uInt32*)aData.getArray() ) = 0xFFFFFFFF;
523 xTempOutStream->writeBytes( aData );
525 // write adv. flags
526 aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0;
527 xTempOutStream->writeBytes( aData );
529 // write compression
530 *( (sal_uInt32*)aData.getArray() ) = 0x0;
531 xTempOutStream->writeBytes( aData );
533 // get the size
534 awt::Size aSize = getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
535 sal_Int32 nIndex = 0;
537 // write width
538 for ( nIndex = 0; nIndex < 4; nIndex++ )
540 aData[nIndex] = (sal_Int8)( aSize.Width % 0x100 );
541 aSize.Width /= 0x100;
543 xTempOutStream->writeBytes( aData );
545 // write height
546 for ( nIndex = 0; nIndex < 4; nIndex++ )
548 aData[nIndex] = (sal_Int8)( aSize.Height % 0x100 );
549 aSize.Height /= 0x100;
551 xTempOutStream->writeBytes( aData );
553 // write garbage, it will be overwritten by the size
554 xTempOutStream->writeBytes( aData );
556 // write first bytes that was used to detect the type
557 xTempOutStream->writeBytes( aSigData );
559 // write the rest of the stream
560 ::comphelper::OStorageHelper::CopyInputToOutput( xInCacheStream, xTempOutStream );
562 // write the size of the stream
563 sal_Int64 nLength = xTempSeek->getLength() - 40;
564 if ( nLength < 0 || nLength >= 0xFFFFFFFF )
566 OSL_ENSURE( sal_False, "Length is not acceptable!" );
567 return;
569 for ( sal_Int32 nInd = 0; nInd < 4; nInd++ )
571 aData[nInd] = (sal_Int8)( ( (sal_uInt64) nLength ) % 0x100 );
572 nLength /= 0x100;
574 xTempSeek->seek( 36 );
575 xTempOutStream->writeBytes( aData );
577 xTempOutStream->flush();
579 xTempSeek->seek( 0 );
580 if ( xCachedSeek.is() )
581 xCachedSeek->seek( 0 );
583 else
584 throw io::IOException(); // TODO:
586 // insert the result file as replacement image
587 ::rtl::OUString aCacheName = ::rtl::OUString::createFromAscii( "\002OlePres000" );
588 if ( xNameContainer->hasByName( aCacheName ) )
589 xNameContainer->replaceByName( aCacheName, uno::makeAny( xTempFile ) );
590 else
591 xNameContainer->insertByName( aCacheName, uno::makeAny( xTempFile ) );
593 uno::Reference< embed::XTransactedObject > xTransacted( xNameContainer, uno::UNO_QUERY );
594 if ( !xTransacted.is() )
595 throw uno::RuntimeException();
597 xTransacted->commit();
600 //------------------------------------------------------
601 void OleEmbeddedObject::RemoveVisualCache_Impl( const uno::Reference< io::XStream >& xTargetStream )
602 throw ( uno::Exception )
604 OSL_ENSURE( xTargetStream.is(), "Invalid argumant!\n" );
605 if ( !xTargetStream.is() )
606 throw uno::RuntimeException();
608 uno::Sequence< uno::Any > aArgs( 2 );
609 aArgs[0] <<= xTargetStream;
610 aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
611 uno::Reference< container::XNameContainer > xNameContainer(
612 m_xFactory->createInstanceWithArguments(
613 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
614 aArgs ),
615 uno::UNO_QUERY );
617 if ( !xNameContainer.is() )
618 throw uno::RuntimeException();
620 for ( sal_uInt8 nInd = 0; nInd < 10; nInd++ )
622 ::rtl::OUString aStreamName = ::rtl::OUString::createFromAscii( "\002OlePres00" );
623 aStreamName += ::rtl::OUString::valueOf( (sal_Int32)nInd );
624 if ( xNameContainer->hasByName( aStreamName ) )
625 xNameContainer->removeByName( aStreamName );
628 uno::Reference< embed::XTransactedObject > xTransacted( xNameContainer, uno::UNO_QUERY );
629 if ( !xTransacted.is() )
630 throw uno::RuntimeException();
632 xTransacted->commit();
635 //------------------------------------------------------
636 void OleEmbeddedObject::SetVisReplInStream( sal_Bool bExists )
638 m_bVisReplInitialized = sal_True;
639 m_bVisReplInStream = bExists;
642 //------------------------------------------------------
643 sal_Bool OleEmbeddedObject::HasVisReplInStream()
645 if ( !m_bVisReplInitialized )
647 if ( m_xCachedVisualRepresentation.is() )
648 SetVisReplInStream( sal_True );
649 else
651 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::HasVisualReplInStream, analizing" );
653 uno::Reference< io::XInputStream > xStream;
655 OSL_ENSURE( !m_pOleComponent || m_aTempURL.getLength(), "The temporary file must exist if there is a component!\n" );
656 if ( m_aTempURL.getLength() )
660 // open temporary file for reading
661 uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
662 m_xFactory->createInstance (
663 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
664 uno::UNO_QUERY );
666 if ( !xTempAccess.is() )
667 throw uno::RuntimeException(); // TODO:
669 xStream = xTempAccess->openFileRead( m_aTempURL );
671 catch( uno::Exception& )
675 if ( !xStream.is() )
676 xStream = m_xObjectStream->getInputStream();
678 if ( xStream.is() )
680 sal_Bool bExists = sal_False;
682 uno::Sequence< uno::Any > aArgs( 2 );
683 aArgs[0] <<= xStream;
684 aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
685 uno::Reference< container::XNameContainer > xNameContainer(
686 m_xFactory->createInstanceWithArguments(
687 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
688 aArgs ),
689 uno::UNO_QUERY );
691 if ( xNameContainer.is() )
693 for ( sal_uInt8 nInd = 0; nInd < 10 && !bExists; nInd++ )
695 ::rtl::OUString aStreamName = ::rtl::OUString::createFromAscii( "\002OlePres00" );
696 aStreamName += ::rtl::OUString::valueOf( (sal_Int32)nInd );
699 bExists = xNameContainer->hasByName( aStreamName );
701 catch( uno::Exception& )
706 SetVisReplInStream( bExists );
711 return m_bVisReplInStream;
714 //------------------------------------------------------
715 uno::Reference< io::XStream > OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation_Impl(
716 const uno::Reference< io::XStream >& xStream,
717 sal_Bool bAllowToRepair50 )
718 throw ()
720 uno::Reference< io::XStream > xResult;
722 if ( xStream.is() )
724 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation, retrieving" );
726 uno::Reference< container::XNameContainer > xNameContainer;
727 uno::Sequence< uno::Any > aArgs( 2 );
728 aArgs[0] <<= xStream;
729 aArgs[1] <<= (sal_Bool)sal_True; // do not create copy
732 xNameContainer = uno::Reference< container::XNameContainer >(
733 m_xFactory->createInstanceWithArguments(
734 ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLESimpleStorage" ),
735 aArgs ),
736 uno::UNO_QUERY );
738 catch( uno::Exception& )
741 if ( xNameContainer.is() )
743 for ( sal_uInt8 nInd = 0; nInd < 10; nInd++ )
745 ::rtl::OUString aStreamName = ::rtl::OUString::createFromAscii( "\002OlePres00" );
746 aStreamName += ::rtl::OUString::valueOf( (sal_Int32)nInd );
747 uno::Reference< io::XStream > xCachedCopyStream;
750 if ( ( xNameContainer->getByName( aStreamName ) >>= xCachedCopyStream ) && xCachedCopyStream.is() )
752 xResult = TryToGetAcceptableFormat_Impl( xCachedCopyStream );
753 if ( xResult.is() )
754 break;
757 catch( uno::Exception& )
760 if ( nInd == 0 )
762 // to be compatible with the old versions Ole10Native is checked after OlePress000
763 aStreamName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\001Ole10Native" ) );
766 if ( ( xNameContainer->getByName( aStreamName ) >>= xCachedCopyStream ) && xCachedCopyStream.is() )
768 xResult = TryToGetAcceptableFormat_Impl( xCachedCopyStream );
769 if ( xResult.is() )
770 break;
773 catch( uno::Exception& )
780 if ( bAllowToRepair50 && !xResult.is() )
782 ::rtl::OUString aOrigContName( RTL_CONSTASCII_USTRINGPARAM( "Ole-Object" ) );
783 if ( xNameContainer->hasByName( aOrigContName ) )
785 uno::Reference< embed::XClassifiedObject > xClassified( xNameContainer, uno::UNO_QUERY_THROW );
786 uno::Sequence< sal_Int8 > aClassID;
787 if ( MimeConfigurationHelper::ClassIDsEqual( xClassified->getClassID(), MimeConfigurationHelper::GetSequenceClassID( SO3_OUT_CLASSID ) ) )
789 // this is an OLE object wrongly stored in 5.0 format
790 // this object must be repaired since SO7 has done it
792 uno::Reference< io::XOutputStream > xOutputStream = xStream->getOutputStream();
793 uno::Reference< io::XTruncate > xTruncate( xOutputStream, uno::UNO_QUERY_THROW );
795 uno::Reference< io::XInputStream > xOrigInputStream;
796 if ( ( xNameContainer->getByName( aOrigContName ) >>= xOrigInputStream )
797 && xOrigInputStream.is() )
799 // the provided input stream must be based on temporary medium and must be independent
800 // from the stream the storage is based on
801 uno::Reference< io::XSeekable > xOrigSeekable( xOrigInputStream, uno::UNO_QUERY );
802 if ( xOrigSeekable.is() )
803 xOrigSeekable->seek( 0 );
805 uno::Reference< lang::XComponent > xNameContDisp( xNameContainer, uno::UNO_QUERY_THROW );
806 xNameContDisp->dispose(); // free the original stream
808 xTruncate->truncate();
809 ::comphelper::OStorageHelper::CopyInputToOutput( xOrigInputStream, xOutputStream );
810 xOutputStream->flush();
812 if ( xStream == m_xObjectStream )
814 if ( m_aTempURL.getLength() )
816 // this is the own stream, so the temporary URL must be cleaned if it exists
817 KillFile_Impl( m_aTempURL, m_xFactory );
818 m_aTempURL = ::rtl::OUString();
821 #ifdef WNT
822 // retry to create the component after recovering
823 GetRidOfComponent();
827 CreateOleComponentAndLoad_Impl( NULL );
828 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
830 catch( uno::Exception& )
832 GetRidOfComponent();
834 #endif
837 xResult = TryToRetrieveCachedVisualRepresentation_Impl( xStream, sal_False );
843 catch( uno::Exception& )
848 return xResult;
851 //------------------------------------------------------
852 void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
853 const uno::Reference< io::XStream >& xNewObjectStream,
854 const ::rtl::OUString& aNewName )
856 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
858 OSL_ENSURE( xNewObjectStream == m_xObjectStream, "The streams must be the same!\n" );
859 return;
862 try {
863 uno::Reference< lang::XComponent > xComponent( m_xObjectStream, uno::UNO_QUERY );
864 OSL_ENSURE( !m_xObjectStream.is() || xComponent.is(), "Wrong stream implementation!" );
865 if ( xComponent.is() )
866 xComponent->dispose();
868 catch ( uno::Exception& )
872 m_xObjectStream = xNewObjectStream;
873 m_xParentStorage = xNewParentStorage;
874 m_aEntryName = aNewName;
877 //------------------------------------------------------
878 void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
879 const ::rtl::OUString& aNewName )
881 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
882 return;
884 sal_Int32 nStreamMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
886 uno::Reference< io::XStream > xNewOwnStream = xNewParentStorage->openStreamElement( aNewName, nStreamMode );
887 OSL_ENSURE( xNewOwnStream.is(), "The method can not return empty reference!" );
889 SwitchOwnPersistence( xNewParentStorage, xNewOwnStream, aNewName );
892 #ifdef WNT
893 //----------------------------------------------
894 sal_Bool OleEmbeddedObject::SaveObject_Impl()
896 sal_Bool bResult = sal_False;
898 if ( m_xClientSite.is() )
902 m_xClientSite->saveObject();
903 bResult = sal_True;
905 catch( uno::Exception& )
910 return bResult;
913 //----------------------------------------------
914 sal_Bool OleEmbeddedObject::OnShowWindow_Impl( sal_Bool bShow )
916 ::osl::ResettableMutexGuard aGuard( m_aMutex );
918 sal_Bool bResult = sal_False;
920 OSL_ENSURE( m_nObjectState != -1, "The object has no persistence!\n" );
921 OSL_ENSURE( m_nObjectState != embed::EmbedStates::LOADED, "The object get OnShowWindow in loaded state!\n" );
922 if ( m_nObjectState == -1 || m_nObjectState == embed::EmbedStates::LOADED )
923 return sal_False;
925 // the object is either activated or deactivated
926 sal_Int32 nOldState = m_nObjectState;
927 if ( bShow && m_nObjectState == embed::EmbedStates::RUNNING )
929 m_nObjectState = embed::EmbedStates::ACTIVE;
930 m_aVerbExecutionController.ObjectIsActive();
932 aGuard.clear();
933 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
935 else if ( !bShow && m_nObjectState == embed::EmbedStates::ACTIVE )
937 m_nObjectState = embed::EmbedStates::RUNNING;
938 aGuard.clear();
939 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
942 if ( m_xClientSite.is() )
946 m_xClientSite->visibilityChanged( bShow );
947 bResult = sal_True;
949 catch( uno::Exception& )
954 return bResult;
957 //------------------------------------------------------
958 void OleEmbeddedObject::OnIconChanged_Impl()
960 // TODO/LATER: currently this notification seems to be impossible
961 // MakeEventListenerNotification_Impl( ::rtl::OUString::createFromAscii( "OnIconChanged" ) );
964 //------------------------------------------------------
965 void OleEmbeddedObject::OnViewChanged_Impl()
967 if ( m_bDisposed )
968 throw lang::DisposedException();
970 // For performance reasons the notification currently is ignored, STAMPIT object is the exception,
971 // it can never be active and never call SaveObject, so it is the only way to detect that it is changed
973 // ==== the STAMPIT related solution =============================
974 // the following variable is used to detect whether the object was modified during verb execution
975 m_aVerbExecutionController.ModificationNotificationIsDone();
977 // The following things are controlled by VerbExecutionController:
978 // - if the verb execution is in progress and the view is changed the object will be stored
979 // after the execution, so there is no need to send the notification.
980 // - the STAMPIT object can never be active.
981 if ( m_aVerbExecutionController.CanDoNotification()
982 && m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE )
984 OSL_ENSURE( MimeConfigurationHelper::ClassIDsEqual( m_aClassID, MimeConfigurationHelper::GetSequenceClassID( 0x852ee1c9, 0x9058, 0x44ba, 0x8c,0x6c,0x0c,0x5f,0xc6,0x6b,0xdb,0x8d ) )
985 || MimeConfigurationHelper::ClassIDsEqual( m_aClassID, MimeConfigurationHelper::GetSequenceClassID( 0xcf1b4491, 0xbea3, 0x4c9f, 0xa7,0x0f,0x22,0x1b,0x1e,0xca,0xef,0x3e ) ),
986 "Expected to be triggered for STAMPIT only! Please contact developers!\n" );
988 // The view is changed while the object is in running state, save the new object
989 m_xCachedVisualRepresentation = uno::Reference< io::XStream >();
990 SaveObject_Impl();
991 MakeEventListenerNotification_Impl( ::rtl::OUString::createFromAscii( "OnVisAreaChanged" ) );
993 // ===============================================================
996 //------------------------------------------------------
997 void OleEmbeddedObject::OnClosed_Impl()
999 if ( m_bDisposed )
1000 throw lang::DisposedException();
1002 if ( m_nObjectState != embed::EmbedStates::LOADED )
1004 sal_Int32 nOldState = m_nObjectState;
1005 m_nObjectState = embed::EmbedStates::LOADED;
1006 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
1010 //------------------------------------------------------
1011 ::rtl::OUString OleEmbeddedObject::CreateTempURLEmpty_Impl()
1013 OSL_ENSURE( !m_aTempURL.getLength(), "The object has already the temporary file!" );
1014 m_aTempURL = GetNewTempFileURL_Impl( m_xFactory );
1016 return m_aTempURL;
1019 //------------------------------------------------------
1020 ::rtl::OUString OleEmbeddedObject::GetTempURL_Impl()
1022 if ( !m_aTempURL.getLength() )
1024 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::GetTempURL_Impl, tempfile creation" );
1026 // if there is no temporary file, it will be created from the own entry
1027 uno::Reference< embed::XOptimizedStorage > xOptParStorage( m_xParentStorage, uno::UNO_QUERY );
1028 if ( xOptParStorage.is() )
1030 m_aTempURL = GetNewFilledTempFile_Impl( xOptParStorage, m_aEntryName, m_xFactory );
1032 else if ( m_xObjectStream.is() )
1034 // load object from the stream
1035 uno::Reference< io::XInputStream > xInStream = m_xObjectStream->getInputStream();
1036 if ( !xInStream.is() )
1037 throw io::IOException(); // TODO: access denied
1039 m_aTempURL = GetNewFilledTempFile_Impl( xInStream, m_xFactory );
1043 return m_aTempURL;
1046 //------------------------------------------------------
1047 void OleEmbeddedObject::CreateOleComponent_Impl( OleComponent* pOleComponent )
1049 if ( !m_pOleComponent )
1051 m_pOleComponent = pOleComponent ? pOleComponent : new OleComponent( m_xFactory, this );
1052 m_pOleComponent->acquire(); // TODO: needs holder?
1054 if ( !m_xClosePreventer.is() )
1055 m_xClosePreventer = uno::Reference< util::XCloseListener >(
1056 static_cast< ::cppu::OWeakObject* >( new OClosePreventer ),
1057 uno::UNO_QUERY );
1059 m_pOleComponent->addCloseListener( m_xClosePreventer );
1063 //------------------------------------------------------
1064 void OleEmbeddedObject::CreateOleComponentAndLoad_Impl( OleComponent* pOleComponent )
1066 if ( !m_pOleComponent )
1068 if ( !m_xObjectStream.is() )
1069 throw uno::RuntimeException();
1071 CreateOleComponent_Impl( pOleComponent );
1073 // after the loading the object can appear as a link
1074 // will be detected later by olecomponent
1076 GetTempURL_Impl();
1077 if ( !m_aTempURL.getLength() )
1078 throw uno::RuntimeException(); // TODO
1080 m_pOleComponent->LoadEmbeddedObject( m_aTempURL );
1084 //------------------------------------------------------
1085 void OleEmbeddedObject::CreateOleComponentFromClipboard_Impl( OleComponent* pOleComponent )
1087 if ( !m_pOleComponent )
1089 if ( !m_xObjectStream.is() )
1090 throw uno::RuntimeException();
1092 CreateOleComponent_Impl( pOleComponent );
1094 // after the loading the object can appear as a link
1095 // will be detected later by olecomponent
1096 m_pOleComponent->CreateObjectFromClipboard();
1100 //------------------------------------------------------
1101 uno::Reference< io::XOutputStream > OleEmbeddedObject::GetStreamForSaving()
1103 if ( !m_xObjectStream.is() )
1104 throw uno::RuntimeException(); //TODO:
1106 uno::Reference< io::XOutputStream > xOutStream = m_xObjectStream->getOutputStream();
1107 if ( !xOutStream.is() )
1108 throw io::IOException(); //TODO: access denied
1110 uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY );
1111 if ( !xTruncate.is() )
1112 throw uno::RuntimeException(); //TODO:
1114 xTruncate->truncate();
1116 return xOutStream;
1119 //----------------------------------------------
1120 void OleEmbeddedObject::StoreObjectToStream( uno::Reference< io::XOutputStream > xOutStream )
1121 throw ( uno::Exception )
1123 // this method should be used only on windows
1124 if ( m_pOleComponent )
1125 m_pOleComponent->StoreOwnTmpIfNecessary();
1127 // now all the changes should be in temporary location
1128 if ( !m_aTempURL )
1129 throw uno::RuntimeException();
1131 // open temporary file for reading
1132 uno::Reference < ucb::XSimpleFileAccess > xTempAccess(
1133 m_xFactory->createInstance (
1134 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
1135 uno::UNO_QUERY );
1137 if ( !xTempAccess.is() )
1138 throw uno::RuntimeException(); // TODO:
1140 uno::Reference< io::XInputStream > xTempInStream = xTempAccess->openFileRead( m_aTempURL );
1141 OSL_ENSURE( xTempInStream.is(), "The object's temporary file can not be reopened for reading!\n" );
1143 // TODO: use bStoreVisReplace
1145 if ( xTempInStream.is() )
1147 // write all the contents to XOutStream
1148 uno::Reference< io::XTruncate > xTrunc( xOutStream, uno::UNO_QUERY );
1149 if ( !xTrunc.is() )
1150 throw uno::RuntimeException(); //TODO:
1152 xTrunc->truncate();
1154 ::comphelper::OStorageHelper::CopyInputToOutput( xTempInStream, xOutStream );
1156 else
1157 throw io::IOException(); // TODO:
1159 // TODO: should the view replacement be in the stream ???
1160 // probably it must be specified on storing
1162 #endif
1163 //------------------------------------------------------
1164 void OleEmbeddedObject::StoreToLocation_Impl(
1165 const uno::Reference< embed::XStorage >& xStorage,
1166 const ::rtl::OUString& sEntName,
1167 const uno::Sequence< beans::PropertyValue >& /*lArguments*/,
1168 const uno::Sequence< beans::PropertyValue >& lObjArgs,
1169 sal_Bool bSaveAs )
1170 throw ( uno::Exception )
1172 // TODO: use lObjArgs
1173 // TODO: exchange StoreVisualReplacement by SO file format version?
1175 if ( m_nObjectState == -1 )
1177 // the object is still not loaded
1178 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1179 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1182 if ( m_bWaitSaveCompleted )
1183 throw embed::WrongStateException(
1184 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1185 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1187 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStream.is(), "The object has no valid persistence!\n" );
1189 sal_Bool bVisReplIsStored = sal_False;
1191 sal_Bool bTryOptimization = sal_False;
1192 sal_Bool bStoreVis = m_bStoreVisRepl;
1193 uno::Reference< io::XStream > xCachedVisualRepresentation;
1194 for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1196 if ( lObjArgs[nInd].Name.equalsAscii( "StoreVisualReplacement" ) )
1197 lObjArgs[nInd].Value >>= bStoreVis;
1198 else if ( lObjArgs[nInd].Name.equalsAscii( "VisualReplacement" ) )
1199 lObjArgs[nInd].Value >>= xCachedVisualRepresentation;
1200 else if ( lObjArgs[nInd].Name.equalsAscii( "CanTryOptimization" ) )
1201 lObjArgs[nInd].Value >>= bTryOptimization;
1204 // ignore visual representation provided from outside if it should not be stored
1205 if ( !bStoreVis )
1206 xCachedVisualRepresentation = uno::Reference< io::XStream >();
1208 if ( bStoreVis && !HasVisReplInStream() && !xCachedVisualRepresentation.is() )
1209 throw io::IOException(); // TODO: there is no cached visual representation and nothing is provided from outside
1211 // if the representation is provided from outside it should be copied to a local stream
1212 sal_Bool bNeedLocalCache = xCachedVisualRepresentation.is();
1214 uno::Reference< io::XStream > xTargetStream;
1216 sal_Bool bStoreLoaded = sal_False;
1217 if ( m_nObjectState == embed::EmbedStates::LOADED
1218 #ifdef WNT
1219 // if the object was NOT modified after storing it can be just copied
1220 // as if it was in loaded state
1221 || ( m_pOleComponent && !m_pOleComponent->IsDirty() )
1222 #endif
1225 sal_Bool bOptimizedCopyingDone = sal_False;
1227 if ( bTryOptimization && bStoreVis == HasVisReplInStream() )
1231 uno::Reference< embed::XOptimizedStorage > xSourceOptStor( m_xParentStorage, uno::UNO_QUERY_THROW );
1232 uno::Reference< embed::XOptimizedStorage > xTargetOptStor( xStorage, uno::UNO_QUERY_THROW );
1233 xSourceOptStor->copyElementDirectlyTo( m_aEntryName, xTargetOptStor, sEntName );
1234 bOptimizedCopyingDone = sal_True;
1236 catch( uno::Exception& )
1241 if ( !bOptimizedCopyingDone )
1243 // if optimized copying fails a normal one should be tried
1244 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
1247 // the locally retrieved representation is always preferable
1248 // since the object is in loaded state the representation is unchanged
1249 if ( m_xCachedVisualRepresentation.is() )
1251 xCachedVisualRepresentation = m_xCachedVisualRepresentation;
1252 bNeedLocalCache = sal_False;
1255 bVisReplIsStored = HasVisReplInStream();
1256 bStoreLoaded = sal_True;
1258 #ifdef WNT
1259 else if ( m_pOleComponent )
1261 xTargetStream =
1262 xStorage->openStreamElement( sEntName, embed::ElementModes::READWRITE );
1263 if ( !xTargetStream.is() )
1264 throw io::IOException(); //TODO: access denied
1266 SetStreamMediaType_Impl( xTargetStream, ::rtl::OUString::createFromAscii( "application/vnd.sun.star.oleobject" ) );
1267 uno::Reference< io::XOutputStream > xOutStream = xTargetStream->getOutputStream();
1268 if ( !xOutStream.is() )
1269 throw io::IOException(); //TODO: access denied
1271 StoreObjectToStream( xOutStream );
1272 bVisReplIsStored = sal_True;
1274 if ( bSaveAs )
1276 // no need to do it on StoreTo since in this case the replacement is in the stream
1277 // and there is no need to cache it even if it is thrown away because the object
1278 // is not changed by StoreTo action
1280 uno::Reference< io::XStream > xTmpCVRepresentation =
1281 TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
1283 // the locally retrieved representation is always preferable
1284 if ( xTmpCVRepresentation.is() )
1286 xCachedVisualRepresentation = xTmpCVRepresentation;
1287 bNeedLocalCache = sal_False;
1291 #endif
1292 else
1294 throw io::IOException(); // TODO
1297 if ( !xTargetStream.is() )
1299 xTargetStream =
1300 xStorage->openStreamElement( sEntName, embed::ElementModes::READWRITE );
1301 if ( !xTargetStream.is() )
1302 throw io::IOException(); //TODO: access denied
1305 LetCommonStoragePassBeUsed_Impl( xTargetStream );
1307 if ( bStoreVis != bVisReplIsStored )
1309 if ( bStoreVis )
1311 if ( !xCachedVisualRepresentation.is() )
1312 xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
1314 OSL_ENSURE( xCachedVisualRepresentation.is(), "No representation is available!" );
1316 // the following copying will be done in case it is SaveAs anyway
1317 // if it is not SaveAs the seekable access is not required currently
1318 // TODO/LATER: may be required in future
1319 if ( bSaveAs )
1321 uno::Reference< io::XSeekable > xCachedSeek( xCachedVisualRepresentation, uno::UNO_QUERY );
1322 if ( !xCachedSeek.is() )
1324 xCachedVisualRepresentation
1325 = GetNewFilledTempStream_Impl( xCachedVisualRepresentation->getInputStream() );
1326 bNeedLocalCache = sal_False;
1330 InsertVisualCache_Impl( xTargetStream, xCachedVisualRepresentation );
1332 else
1334 // the removed representation could be cached by this method
1335 if ( !xCachedVisualRepresentation.is() )
1336 xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
1338 RemoveVisualCache_Impl( xTargetStream );
1342 if ( bSaveAs )
1344 m_bWaitSaveCompleted = sal_True;
1345 m_xNewObjectStream = xTargetStream;
1346 m_xNewParentStorage = xStorage;
1347 m_aNewEntryName = sEntName;
1348 m_bNewVisReplInStream = bStoreVis;
1349 m_bStoreLoaded = bStoreLoaded;
1351 if ( xCachedVisualRepresentation.is() )
1353 if ( bNeedLocalCache )
1354 m_xNewCachedVisRepl = GetNewFilledTempStream_Impl( xCachedVisualRepresentation->getInputStream() );
1355 else
1356 m_xNewCachedVisRepl = xCachedVisualRepresentation;
1359 // TODO: register listeners for storages above, in case they are disposed
1360 // an exception will be thrown on saveCompleted( true )
1362 else
1364 uno::Reference< lang::XComponent > xComp( xTargetStream, uno::UNO_QUERY );
1365 if ( xComp.is() )
1367 try {
1368 xComp->dispose();
1369 } catch( uno::Exception& )
1376 //------------------------------------------------------
1377 void SAL_CALL OleEmbeddedObject::setPersistentEntry(
1378 const uno::Reference< embed::XStorage >& xStorage,
1379 const ::rtl::OUString& sEntName,
1380 sal_Int32 nEntryConnectionMode,
1381 const uno::Sequence< beans::PropertyValue >& lArguments,
1382 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1383 throw ( lang::IllegalArgumentException,
1384 embed::WrongStateException,
1385 io::IOException,
1386 uno::Exception,
1387 uno::RuntimeException )
1389 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::setPersistentEntry" );
1391 // begin wrapping related part ====================
1392 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1393 if ( xWrappedObject.is() )
1395 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1396 xWrappedObject->setPersistentEntry( xStorage, sEntName, nEntryConnectionMode, lArguments, lObjArgs );
1397 return;
1399 // end wrapping related part ====================
1401 // TODO: use lObjArgs
1403 // the type of the object must be already set
1404 // a kind of typedetection should be done in the factory;
1405 // the only exception is object initialized from a stream,
1406 // the class ID will be detected from the stream
1408 ::osl::MutexGuard aGuard( m_aMutex );
1409 if ( m_bDisposed )
1410 throw lang::DisposedException(); // TODO
1412 if ( !xStorage.is() )
1413 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
1414 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1415 1 );
1417 if ( !sEntName.getLength() )
1418 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
1419 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1420 2 );
1422 // May be LOADED should be forbidden here ???
1423 if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1424 && ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) )
1426 // if the object is not loaded
1427 // it can not get persistant representation without initialization
1429 // if the object is loaded
1430 // it can switch persistant representation only without initialization
1432 throw embed::WrongStateException(
1433 ::rtl::OUString::createFromAscii( "Can't change persistant representation of activated object!\n" ),
1434 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1437 if ( m_bWaitSaveCompleted )
1439 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1440 saveCompleted( ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) ) );
1441 else
1442 throw embed::WrongStateException(
1443 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1444 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1447 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
1448 if ( !xNameAccess.is() )
1449 throw uno::RuntimeException(); //TODO
1451 // detect entry existence
1452 sal_Bool bElExists = xNameAccess->hasByName( sEntName );
1454 m_bReadOnly = sal_False;
1455 sal_Int32 nInd = 0;
1456 for ( nInd = 0; nInd < lArguments.getLength(); nInd++ )
1457 if ( lArguments[nInd].Name.equalsAscii( "ReadOnly" ) )
1458 lArguments[nInd].Value >>= m_bReadOnly;
1460 #ifdef WNT
1461 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
1462 #endif
1464 SwitchOwnPersistence( xStorage, sEntName );
1466 for ( nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1467 if ( lObjArgs[nInd].Name.equalsAscii( "StoreVisualReplacement" ) )
1468 lObjArgs[nInd].Value >>= m_bStoreVisRepl;
1470 #ifdef WNT
1471 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT )
1473 if ( m_bFromClipboard )
1475 // the object should be initialized from clipboard
1476 // inpossibility to initialize the object means error here
1477 CreateOleComponentFromClipboard_Impl( NULL );
1478 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
1479 m_pOleComponent->RunObject();
1480 m_nObjectState = embed::EmbedStates::RUNNING;
1482 else if ( bElExists )
1484 // load object from the stream
1485 // after the loading the object can appear as a link
1486 // will be detected by olecomponent
1489 CreateOleComponentAndLoad_Impl( NULL );
1490 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
1492 catch( uno::Exception& )
1494 // TODO/LATER: detect classID of the object if possible
1495 // means that the object inprocess server could not be successfuly instantiated
1496 GetRidOfComponent();
1499 m_nObjectState = embed::EmbedStates::LOADED;
1501 else
1503 // create a new object
1504 CreateOleComponent_Impl();
1505 m_pOleComponent->CreateNewEmbeddedObject( m_aClassID );
1506 m_pOleComponent->RunObject();
1507 m_nObjectState = embed::EmbedStates::RUNNING;
1510 else
1512 if ( ( nStorageMode & embed::ElementModes::READWRITE ) != embed::ElementModes::READWRITE )
1513 throw io::IOException();
1515 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1517 // the document just already changed its stream to store to;
1518 // the links to OLE documents switch their persistence in the same way
1519 // as normal embedded objects
1521 else if ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT )
1523 // create a new object, that will be stored in specified stream
1524 CreateOleComponent_Impl();
1526 m_pOleComponent->CreateNewEmbeddedObject( m_aClassID );
1527 m_pOleComponent->RunObject();
1528 m_nObjectState = embed::EmbedStates::RUNNING;
1530 else if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
1532 // use URL ( may be content or stream later ) from MediaDescriptor to initialize object
1533 ::rtl::OUString aURL;
1534 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1535 if ( lArguments[nInd].Name.equalsAscii( "URL" ) )
1536 lArguments[nInd].Value >>= aURL;
1538 if ( !aURL.getLength() )
1539 throw lang::IllegalArgumentException(
1540 ::rtl::OUString::createFromAscii( "Empty URL is provided in the media descriptor!\n" ),
1541 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1542 4 );
1544 CreateOleComponent_Impl();
1546 // TODO: the m_bIsLink value must be set already
1547 if ( !m_bIsLink )
1548 m_pOleComponent->CreateObjectFromFile( aURL );
1549 else
1550 m_pOleComponent->CreateLinkFromFile( aURL );
1552 m_pOleComponent->RunObject();
1553 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
1555 m_nObjectState = embed::EmbedStates::RUNNING;
1557 //else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT )
1559 //TODO:
1561 else
1562 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Wrong connection mode is provided!\n" ),
1563 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1564 3 );
1566 #else
1567 // On unix the ole object can not do anything except storing itself somewere
1568 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT && bElExists )
1570 // TODO/LATER: detect classID of the object
1571 // can be a real problem for the links
1573 m_nObjectState = embed::EmbedStates::LOADED;
1575 else if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1577 // do nothing, the object has already switched it's persistence
1579 else
1580 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Wrong connection mode is provided!\n" ),
1581 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1582 3 );
1584 #endif
1587 //------------------------------------------------------
1588 void SAL_CALL OleEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage,
1589 const ::rtl::OUString& sEntName,
1590 const uno::Sequence< beans::PropertyValue >& lArguments,
1591 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1592 throw ( lang::IllegalArgumentException,
1593 embed::WrongStateException,
1594 io::IOException,
1595 uno::Exception,
1596 uno::RuntimeException )
1598 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::storeToEntry" );
1600 // begin wrapping related part ====================
1601 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1602 if ( xWrappedObject.is() )
1604 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1605 xWrappedObject->storeToEntry( xStorage, sEntName, lArguments, lObjArgs );
1606 return;
1608 // end wrapping related part ====================
1610 ::osl::MutexGuard aGuard( m_aMutex );
1611 if ( m_bDisposed )
1612 throw lang::DisposedException(); // TODO
1614 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
1616 StoreToLocation_Impl( xStorage, sEntName, lArguments, lObjArgs, sal_False );
1618 // TODO: should the listener notification be done?
1621 //------------------------------------------------------
1622 void SAL_CALL OleEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage,
1623 const ::rtl::OUString& sEntName,
1624 const uno::Sequence< beans::PropertyValue >& lArguments,
1625 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1626 throw ( lang::IllegalArgumentException,
1627 embed::WrongStateException,
1628 io::IOException,
1629 uno::Exception,
1630 uno::RuntimeException )
1632 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::storeAsEntry" );
1634 // begin wrapping related part ====================
1635 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1636 if ( xWrappedObject.is() )
1638 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1639 xWrappedObject->storeAsEntry( xStorage, sEntName, lArguments, lObjArgs );
1640 return;
1642 // end wrapping related part ====================
1644 ::osl::MutexGuard aGuard( m_aMutex );
1645 if ( m_bDisposed )
1646 throw lang::DisposedException(); // TODO
1648 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
1650 StoreToLocation_Impl( xStorage, sEntName, lArguments, lObjArgs, sal_True );
1652 // TODO: should the listener notification be done here or in saveCompleted?
1655 //------------------------------------------------------
1656 void SAL_CALL OleEmbeddedObject::saveCompleted( sal_Bool bUseNew )
1657 throw ( embed::WrongStateException,
1658 uno::Exception,
1659 uno::RuntimeException )
1661 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::saveCompleted" );
1663 // begin wrapping related part ====================
1664 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1665 if ( xWrappedObject.is() )
1667 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1668 xWrappedObject->saveCompleted( bUseNew );
1669 return;
1671 // end wrapping related part ====================
1673 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1674 if ( m_bDisposed )
1675 throw lang::DisposedException(); // TODO
1677 if ( m_nObjectState == -1 )
1679 // the object is still not loaded
1680 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1681 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1684 // it is allowed to call saveCompleted( false ) for nonstored objects
1685 if ( !m_bWaitSaveCompleted && !bUseNew )
1686 return;
1688 OSL_ENSURE( m_bWaitSaveCompleted, "Unexpected saveCompleted() call!\n" );
1689 if ( !m_bWaitSaveCompleted )
1690 throw io::IOException(); // TODO: illegal call
1692 OSL_ENSURE( m_xNewObjectStream.is() && m_xNewParentStorage.is() , "Internal object information is broken!\n" );
1693 if ( !m_xNewObjectStream.is() || !m_xNewParentStorage.is() )
1694 throw uno::RuntimeException(); // TODO: broken internal information
1696 if ( bUseNew )
1698 SwitchOwnPersistence( m_xNewParentStorage, m_xNewObjectStream, m_aNewEntryName );
1699 m_bStoreVisRepl = m_bNewVisReplInStream;
1700 SetVisReplInStream( m_bNewVisReplInStream );
1701 m_xCachedVisualRepresentation = m_xNewCachedVisRepl;
1703 else
1705 // close remembered stream
1706 try {
1707 uno::Reference< lang::XComponent > xComponent( m_xNewObjectStream, uno::UNO_QUERY );
1708 OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" );
1709 if ( xComponent.is() )
1710 xComponent->dispose();
1712 catch ( uno::Exception& )
1717 sal_Bool bStoreLoaded = m_bStoreLoaded;
1719 m_xNewObjectStream = uno::Reference< io::XStream >();
1720 m_xNewParentStorage = uno::Reference< embed::XStorage >();
1721 m_aNewEntryName = ::rtl::OUString();
1722 m_bWaitSaveCompleted = sal_False;
1723 m_bNewVisReplInStream = sal_False;
1724 m_xNewCachedVisRepl = uno::Reference< io::XStream >();
1725 m_bStoreLoaded = sal_False;
1727 if ( bUseNew && m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded
1728 && m_nObjectState != embed::EmbedStates::LOADED )
1730 // the object replacement image should be updated, so the cached size as well
1731 m_bHasCachedSize = sal_False;
1734 // the call will cache the size in case of success
1735 // probably it might need to be done earlier, while the object is in active state
1736 getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1738 catch( uno::Exception& )
1742 aGuard.clear();
1743 if ( bUseNew )
1745 MakeEventListenerNotification_Impl( ::rtl::OUString::createFromAscii( "OnSaveAsDone" ) );
1747 // the object can be changed only on windows
1748 // the notification should be done only if the object is not in loaded state
1749 if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
1751 MakeEventListenerNotification_Impl( ::rtl::OUString::createFromAscii( "OnVisAreaChanged" ) );
1756 //------------------------------------------------------
1757 sal_Bool SAL_CALL OleEmbeddedObject::hasEntry()
1758 throw ( embed::WrongStateException,
1759 uno::RuntimeException )
1761 // begin wrapping related part ====================
1762 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1763 if ( xWrappedObject.is() )
1765 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1766 return xWrappedObject->hasEntry();
1768 // end wrapping related part ====================
1770 ::osl::MutexGuard aGuard( m_aMutex );
1771 if ( m_bDisposed )
1772 throw lang::DisposedException(); // TODO
1774 if ( m_bWaitSaveCompleted )
1775 throw embed::WrongStateException(
1776 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1777 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1779 if ( m_xObjectStream.is() )
1780 return sal_True;
1782 return sal_False;
1785 //------------------------------------------------------
1786 ::rtl::OUString SAL_CALL OleEmbeddedObject::getEntryName()
1787 throw ( embed::WrongStateException,
1788 uno::RuntimeException )
1790 // begin wrapping related part ====================
1791 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1792 if ( xWrappedObject.is() )
1794 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1795 return xWrappedObject->getEntryName();
1797 // end wrapping related part ====================
1799 ::osl::MutexGuard aGuard( m_aMutex );
1800 if ( m_bDisposed )
1801 throw lang::DisposedException(); // TODO
1803 if ( m_nObjectState == -1 )
1805 // the object is still not loaded
1806 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
1807 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1810 if ( m_bWaitSaveCompleted )
1811 throw embed::WrongStateException(
1812 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1813 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1815 return m_aEntryName;
1819 //------------------------------------------------------
1820 void SAL_CALL OleEmbeddedObject::storeOwn()
1821 throw ( embed::WrongStateException,
1822 io::IOException,
1823 uno::Exception,
1824 uno::RuntimeException )
1826 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::storeOwn" );
1828 // begin wrapping related part ====================
1829 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1830 if ( xWrappedObject.is() )
1832 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1833 xWrappedObject->storeOwn();
1834 return;
1836 // end wrapping related part ====================
1838 // during switching from Activated to Running and from Running to Loaded states the object will
1839 // ask container to store the object, the container has to make decision
1840 // to do so or not
1842 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1843 if ( m_bDisposed )
1844 throw lang::DisposedException(); // TODO
1846 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
1848 if ( m_nObjectState == -1 )
1850 // the object is still not loaded
1851 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1852 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1855 if ( m_bWaitSaveCompleted )
1856 throw embed::WrongStateException(
1857 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1858 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1860 if ( m_bReadOnly )
1861 throw io::IOException(); // TODO: access denied
1863 LetCommonStoragePassBeUsed_Impl( m_xObjectStream );
1865 sal_Bool bStoreLoaded = sal_True;
1867 #ifdef WNT
1868 if ( m_nObjectState != embed::EmbedStates::LOADED && m_pOleComponent && m_pOleComponent->IsDirty() )
1870 bStoreLoaded = sal_False;
1872 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStream.is(), "The object has no valid persistence!\n" );
1874 if ( !m_xObjectStream.is() )
1875 throw io::IOException(); //TODO: access denied
1877 SetStreamMediaType_Impl( m_xObjectStream, ::rtl::OUString::createFromAscii( "application/vnd.sun.star.oleobject" ) );
1878 uno::Reference< io::XOutputStream > xOutStream = m_xObjectStream->getOutputStream();
1879 if ( !xOutStream.is() )
1880 throw io::IOException(); //TODO: access denied
1882 if ( m_bIsLink )
1884 // just let the link store itself
1885 // in case visual repersentation must be stored also
1886 // the procedure should be the same as for embedded objects
1888 uno::Reference< io::XOutputStream > xOutStream = GetStreamForSaving();
1890 // should the component detect that it is a link???
1891 StoreObjectToStream( xOutStream );
1893 else
1895 uno::Reference< io::XOutputStream > xOutStream = GetStreamForSaving();
1896 StoreObjectToStream( xOutStream );
1899 // the replacement is changed probably, and it must be in the object stream
1900 if ( !m_pOleComponent->IsWorkaroundActive() )
1901 m_xCachedVisualRepresentation = uno::Reference< io::XStream >();
1902 SetVisReplInStream( sal_True );
1904 #endif
1906 if ( m_bStoreVisRepl != HasVisReplInStream() )
1908 if ( m_bStoreVisRepl )
1910 // the m_xCachedVisualRepresentation must be set or it should be already stored
1911 if ( m_xCachedVisualRepresentation.is() )
1912 InsertVisualCache_Impl( m_xObjectStream, m_xCachedVisualRepresentation );
1913 else
1915 m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream );
1916 OSL_ENSURE( m_xCachedVisualRepresentation.is(), "No representation is available!" );
1919 else
1921 if ( !m_xCachedVisualRepresentation.is() )
1922 m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream );
1923 RemoveVisualCache_Impl( m_xObjectStream );
1926 SetVisReplInStream( m_bStoreVisRepl );
1929 if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
1931 // the object replacement image should be updated, so the cached size as well
1932 m_bHasCachedSize = sal_False;
1935 // the call will cache the size in case of success
1936 // probably it might need to be done earlier, while the object is in active state
1937 getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1939 catch( uno::Exception& )
1943 aGuard.clear();
1945 MakeEventListenerNotification_Impl( ::rtl::OUString::createFromAscii( "OnSaveDone" ) );
1947 // the object can be changed only on Windows
1948 // the notification should be done only if the object is not in loaded state
1949 if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
1950 MakeEventListenerNotification_Impl( ::rtl::OUString::createFromAscii( "OnVisAreaChanged" ) );
1953 //------------------------------------------------------
1954 sal_Bool SAL_CALL OleEmbeddedObject::isReadonly()
1955 throw ( embed::WrongStateException,
1956 uno::RuntimeException )
1958 // begin wrapping related part ====================
1959 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1960 if ( xWrappedObject.is() )
1962 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1963 return xWrappedObject->isReadonly();
1965 // end wrapping related part ====================
1967 ::osl::MutexGuard aGuard( m_aMutex );
1968 if ( m_bDisposed )
1969 throw lang::DisposedException(); // TODO
1971 if ( m_nObjectState == -1 )
1973 // the object is still not loaded
1974 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
1975 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1978 if ( m_bWaitSaveCompleted )
1979 throw embed::WrongStateException(
1980 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1981 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1983 return m_bReadOnly;
1986 //------------------------------------------------------
1987 void SAL_CALL OleEmbeddedObject::reload(
1988 const uno::Sequence< beans::PropertyValue >& lArguments,
1989 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1990 throw ( lang::IllegalArgumentException,
1991 embed::WrongStateException,
1992 io::IOException,
1993 uno::Exception,
1994 uno::RuntimeException )
1996 // begin wrapping related part ====================
1997 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1998 if ( xWrappedObject.is() )
2000 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2001 xWrappedObject->reload( lArguments, lObjArgs );
2002 return;
2004 // end wrapping related part ====================
2006 // TODO: use lObjArgs
2008 ::osl::MutexGuard aGuard( m_aMutex );
2009 if ( m_bDisposed )
2010 throw lang::DisposedException(); // TODO
2012 if ( m_nObjectState == -1 )
2014 // the object is still not loaded
2015 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
2016 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
2019 if ( m_bWaitSaveCompleted )
2020 throw embed::WrongStateException(
2021 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
2022 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
2024 // TODO:
2025 // throw away current document
2026 // load new document from current storage
2027 // use meaningfull part of lArguments
2030 //------------------------------------------------------
2031 void SAL_CALL OleEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage,
2032 const ::rtl::OUString& sEntName )
2033 throw ( lang::IllegalArgumentException,
2034 embed::WrongStateException,
2035 io::IOException,
2036 uno::Exception,
2037 uno::RuntimeException )
2039 // begin wrapping related part ====================
2040 uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
2041 if ( xWrappedObject.is() )
2043 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2044 xWrappedObject->breakLink( xStorage, sEntName );
2045 return;
2047 // end wrapping related part ====================
2049 ::osl::MutexGuard aGuard( m_aMutex );
2050 if ( m_bDisposed )
2051 throw lang::DisposedException(); // TODO
2053 if ( !xStorage.is() )
2054 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
2055 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
2056 1 );
2058 if ( !sEntName.getLength() )
2059 throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
2060 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
2061 2 );
2063 // TODO: The object must be at least in Running state;
2064 if ( !m_bIsLink || m_nObjectState == -1 || !m_pOleComponent )
2066 // it must be a linked initialized object
2067 throw embed::WrongStateException(
2068 ::rtl::OUString::createFromAscii( "The object is not a valid linked object!\n" ),
2069 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
2072 if ( m_bReadOnly )
2073 throw io::IOException(); // TODO: Access denied
2075 if ( m_bWaitSaveCompleted )
2076 throw embed::WrongStateException(
2077 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
2078 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
2081 #ifdef WNT
2082 if ( m_pOleComponent )
2084 // TODO: create an object based on the link
2086 // disconnect the old temporary URL
2087 ::rtl::OUString aOldTempURL = m_aTempURL;
2088 m_aTempURL = ::rtl::OUString();
2090 OleComponent* pNewOleComponent = new OleComponent( m_xFactory, this );
2091 try {
2092 pNewOleComponent->InitEmbeddedCopyOfLink( m_pOleComponent );
2094 catch ( uno::Exception& )
2096 delete pNewOleComponent;
2097 if ( m_aTempURL )
2098 KillFile_Impl( m_aTempURL, m_xFactory );
2099 m_aTempURL = aOldTempURL;
2100 throw;
2103 try {
2104 GetRidOfComponent();
2106 catch( uno::Exception& )
2108 delete pNewOleComponent;
2109 if ( m_aTempURL )
2110 KillFile_Impl( m_aTempURL, m_xFactory );
2111 m_aTempURL = aOldTempURL;
2112 throw;
2115 KillFile_Impl( aOldTempURL, m_xFactory );
2117 CreateOleComponent_Impl( pNewOleComponent );
2119 if ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) )
2120 SwitchOwnPersistence( xStorage, sEntName );
2122 if ( m_nObjectState != embed::EmbedStates::LOADED )
2124 // TODO: should we activate the new object if the link was activated?
2126 sal_Int32 nTargetState = m_nObjectState;
2127 m_nObjectState = embed::EmbedStates::LOADED;
2129 if ( m_nObjectState == embed::EmbedStates::RUNNING )
2130 m_pOleComponent->RunObject(); // the object already was in running state, the server must be installed
2131 else // m_nObjectState == embed::EmbedStates::ACTIVE
2133 m_pOleComponent->RunObject(); // the object already was in running state, the server must be installed
2134 m_pOleComponent->ExecuteVerb( embed::EmbedVerbs::MS_OLEVERB_OPEN );
2137 m_nObjectState = nTargetState;
2140 m_bIsLink = sal_False;
2141 m_aLinkURL = ::rtl::OUString();
2143 else
2144 #endif
2146 throw io::IOException(); //TODO:
2150 //------------------------------------------------------
2151 sal_Bool SAL_CALL OleEmbeddedObject::isLink()
2152 throw ( embed::WrongStateException,
2153 uno::RuntimeException )
2155 // begin wrapping related part ====================
2156 uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
2157 if ( xWrappedObject.is() )
2159 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2160 return xWrappedObject->isLink();
2162 // end wrapping related part ====================
2164 ::osl::MutexGuard aGuard( m_aMutex );
2165 if ( m_bDisposed )
2166 throw lang::DisposedException(); // TODO
2168 return m_bIsLink;
2171 //------------------------------------------------------
2172 ::rtl::OUString SAL_CALL OleEmbeddedObject::getLinkURL()
2173 throw ( embed::WrongStateException,
2174 uno::Exception,
2175 uno::RuntimeException )
2177 // begin wrapping related part ====================
2178 uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
2179 if ( xWrappedObject.is() )
2181 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2182 return xWrappedObject->getLinkURL();
2184 // end wrapping related part ====================
2186 ::osl::MutexGuard aGuard( m_aMutex );
2187 if ( m_bDisposed )
2188 throw lang::DisposedException(); // TODO
2190 if ( m_bWaitSaveCompleted )
2191 throw embed::WrongStateException(
2192 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
2193 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
2195 if ( !m_bIsLink )
2196 throw embed::WrongStateException(
2197 ::rtl::OUString::createFromAscii( "The object is not a link object!\n" ),
2198 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
2200 // TODO: probably the link URL can be retrieved from OLE
2202 return m_aLinkURL;