fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / embeddedobj / source / msole / olepersist.cxx
blob00a81617ff3c15ea6a0ea0bff2e6c09b09ca4934
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <oleembobj.hxx>
21 #include <olepersist.hxx>
22 #include <com/sun/star/embed/EmbedStates.hpp>
23 #include <com/sun/star/embed/EmbedVerbs.hpp>
24 #include <com/sun/star/embed/EntryInitModes.hpp>
25 #include <com/sun/star/embed/XStorage.hpp>
26 #include <com/sun/star/embed/XTransactedObject.hpp>
27 #include <com/sun/star/embed/ElementModes.hpp>
28 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
29 #include <com/sun/star/embed/Aspects.hpp>
30 #include <com/sun/star/embed/XOptimizedStorage.hpp>
31 #include <com/sun/star/lang/XComponent.hpp>
32 #include <com/sun/star/lang/DisposedException.hpp>
33 #include <com/sun/star/container/XNameAccess.hpp>
34 #include <com/sun/star/container/XNameContainer.hpp>
35 #include <com/sun/star/io/TempFile.hpp>
36 #include <com/sun/star/io/XSeekable.hpp>
37 #include <com/sun/star/io/XTruncate.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
41 #include <comphelper/processfactory.hxx>
42 #include <comphelper/storagehelper.hxx>
43 #include <comphelper/mimeconfighelper.hxx>
44 #include <comphelper/classids.hxx>
45 #include <osl/diagnose.h>
46 #include <osl/thread.hxx>
48 #include <closepreventer.hxx>
50 #if defined WNT
51 #include <olecomponent.hxx>
52 #endif
54 using namespace ::com::sun::star;
55 using namespace ::comphelper;
58 bool KillFile_Impl( const OUString& aURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
60 if ( !xFactory.is() )
61 return false;
63 bool bRet = false;
65 try
67 uno::Reference < ucb::XSimpleFileAccess3 > xAccess(
68 ucb::SimpleFileAccess::create( comphelper::getComponentContext(xFactory) ) );
70 xAccess->kill( aURL );
71 bRet = true;
73 catch( const uno::Exception& )
77 return bRet;
81 OUString GetNewTempFileURL_Impl( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
83 SAL_WARN_IF( !xFactory.is(), "embeddedobj.ole", "No factory is provided!" );
85 OUString aResult;
87 uno::Reference < beans::XPropertySet > xTempFile(
88 io::TempFile::create(comphelper::getComponentContext(xFactory)),
89 uno::UNO_QUERY_THROW );
91 try {
92 xTempFile->setPropertyValue("RemoveFile", uno::makeAny( sal_False ) );
93 uno::Any aUrl = xTempFile->getPropertyValue("Uri");
94 aUrl >>= aResult;
96 catch ( const uno::Exception& )
100 if ( aResult.isEmpty() )
101 throw uno::RuntimeException(); // TODO: can not create tempfile
103 return aResult;
107 OUString GetNewFilledTempFile_Impl( const uno::Reference< io::XInputStream >& xInStream,
108 const uno::Reference< lang::XMultiServiceFactory >& xFactory )
109 throw ( io::IOException,
110 uno::RuntimeException )
112 OSL_ENSURE( xInStream.is() && xFactory.is(), "Wrong parameters are provided!\n" );
114 OUString aResult = GetNewTempFileURL_Impl( xFactory );
116 if ( !aResult.isEmpty() )
118 try {
119 uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(
120 ucb::SimpleFileAccess::create( comphelper::getComponentContext(xFactory) ) );
122 uno::Reference< io::XOutputStream > xTempOutStream = xTempAccess->openFileWrite( aResult );
123 if ( xTempOutStream.is() )
125 // copy stream contents to the file
126 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOutStream );
127 xTempOutStream->closeOutput();
128 xTempOutStream = uno::Reference< io::XOutputStream >();
130 else
131 throw io::IOException(); // TODO:
133 catch( const packages::WrongPasswordException& )
135 KillFile_Impl( aResult, xFactory );
136 throw io::IOException(); //TODO:
138 catch( const io::IOException& )
140 KillFile_Impl( aResult, xFactory );
141 throw;
143 catch( const uno::RuntimeException& )
145 KillFile_Impl( aResult, xFactory );
146 throw;
148 catch( const uno::Exception& )
150 KillFile_Impl( aResult, xFactory );
151 aResult.clear();
155 return aResult;
157 #ifdef WNT
158 OUString GetNewFilledTempFile_Impl( const uno::Reference< embed::XOptimizedStorage >& xParentStorage, const OUString& aEntryName, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
159 throw( io::IOException, uno::RuntimeException )
161 OUString aResult;
165 uno::Reference < beans::XPropertySet > xTempFile(
166 io::TempFile::create(comphelper::getComponentContext(xFactory)),
167 uno::UNO_QUERY );
168 uno::Reference < io::XStream > xTempStream( xTempFile, uno::UNO_QUERY_THROW );
170 xParentStorage->copyStreamElementData( aEntryName, xTempStream );
172 xTempFile->setPropertyValue("RemoveFile", uno::makeAny( sal_False ) );
173 uno::Any aUrl = xTempFile->getPropertyValue("Uri");
174 aUrl >>= aResult;
176 catch( const uno::RuntimeException& )
178 throw;
180 catch( const uno::Exception& )
184 if ( aResult.isEmpty() )
185 throw io::IOException();
187 return aResult;
191 void SetStreamMediaType_Impl( const uno::Reference< io::XStream >& xStream, const OUString& aMediaType )
193 uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY );
194 if ( !xPropSet.is() )
195 throw uno::RuntimeException(); // TODO: all the storage streams must support XPropertySet
197 xPropSet->setPropertyValue("MediaType", uno::makeAny( aMediaType ) );
199 #endif
201 void LetCommonStoragePassBeUsed_Impl( const uno::Reference< io::XStream >& xStream )
203 uno::Reference< beans::XPropertySet > xPropSet( xStream, uno::UNO_QUERY );
204 if ( !xPropSet.is() )
205 throw uno::RuntimeException(); // Only StorageStreams must be provided here, they must implement the interface
207 xPropSet->setPropertyValue("UseCommonStoragePasswordEncryption",
208 uno::makeAny( true ) );
210 #ifdef WNT
212 void VerbExecutionController::StartControlExecution()
214 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
216 // the class is used to detect STAMPIT object, that can never be active
217 if ( !m_bVerbExecutionInProgress && !m_bWasEverActive )
219 m_bVerbExecutionInProgress = sal_True;
220 m_nVerbExecutionThreadIdentifier = osl::Thread::getCurrentIdentifier();
221 m_bChangedOnVerbExecution = sal_False;
226 sal_Bool VerbExecutionController::EndControlExecution_WasModified()
228 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
230 sal_Bool bResult = sal_False;
231 if ( m_bVerbExecutionInProgress && m_nVerbExecutionThreadIdentifier == osl::Thread::getCurrentIdentifier() )
233 bResult = m_bChangedOnVerbExecution;
234 m_bVerbExecutionInProgress = sal_False;
237 return bResult;
241 void VerbExecutionController::ModificationNotificationIsDone()
243 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
245 if ( m_bVerbExecutionInProgress && osl::Thread::getCurrentIdentifier() == m_nVerbExecutionThreadIdentifier )
246 m_bChangedOnVerbExecution = sal_True;
248 #endif
250 void VerbExecutionController::LockNotification()
252 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
253 if ( m_nNotificationLock < SAL_MAX_INT32 )
254 m_nNotificationLock++;
258 void VerbExecutionController::UnlockNotification()
260 osl::MutexGuard aGuard( m_aVerbExecutionMutex );
261 if ( m_nNotificationLock > 0 )
262 m_nNotificationLock--;
266 uno::Reference< io::XStream > OleEmbeddedObject::GetNewFilledTempStream_Impl( const uno::Reference< io::XInputStream >& xInStream )
267 throw( io::IOException, uno::RuntimeException )
269 SAL_WARN_IF( !xInStream.is(), "embeddedobj.ole", "Wrong parameter is provided!" );
271 uno::Reference < io::XStream > xTempFile(
272 io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
273 uno::UNO_QUERY_THROW );
275 uno::Reference< io::XOutputStream > xTempOutStream = xTempFile->getOutputStream();
276 if ( xTempOutStream.is() )
278 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOutStream );
279 xTempOutStream->flush();
281 else
282 throw io::IOException(); // TODO:
284 return xTempFile;
288 uno::Reference< io::XStream > OleEmbeddedObject::TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream )
289 throw ( uno::Exception )
291 // TODO/LATER: Actually this should be done by a centralized component ( may be a graphical filter )
292 if ( !m_xFactory.is() )
293 throw uno::RuntimeException();
295 uno::Reference< io::XInputStream > xInStream = xStream->getInputStream();
296 if ( !xInStream.is() )
297 throw uno::RuntimeException();
299 uno::Reference< io::XSeekable > xSeek( xStream, uno::UNO_QUERY_THROW );
300 xSeek->seek( 0 );
302 uno::Sequence< sal_Int8 > aData( 8 );
303 sal_Int32 nRead = xInStream->readBytes( aData, 8 );
304 xSeek->seek( 0 );
306 if ( ( nRead >= 2 && aData[0] == 'B' && aData[1] == 'M' )
307 || ( nRead >= 4 && aData[0] == 1 && aData[1] == 0 && aData[2] == 9 && aData[3] == 0 ) )
309 // it should be a bitmap or a Metafile
310 return xStream;
314 sal_uInt32 nHeaderOffset = 0;
315 if ( ( nRead >= 8 && aData[0] == -1 && aData[1] == -1 && aData[2] == -1 && aData[3] == -1 )
316 && ( aData[4] == 2 || aData[4] == 3 || aData[4] == 14 ) && aData[5] == 0 && aData[6] == 0 && aData[7] == 0 )
318 nHeaderOffset = 40;
319 xSeek->seek( 8 );
321 // TargetDevice might be used in future, currently the cache has specified NULL
322 uno::Sequence< sal_Int8 > aHeadData( 4 );
323 nRead = xInStream->readBytes( aHeadData, 4 );
324 sal_uInt32 nLen = 0;
325 if ( nRead == 4 && aHeadData.getLength() == 4 )
326 nLen = ( ( ( (sal_uInt32)aHeadData[3] * 0x100 + (sal_uInt32)aHeadData[2] ) * 0x100 ) + (sal_uInt32)aHeadData[1] ) * 0x100 + (sal_uInt32)aHeadData[0];
327 if ( nLen > 4 )
329 xInStream->skipBytes( nLen - 4 );
330 nHeaderOffset += nLen - 4;
334 else if ( nRead > 4 )
336 // check whether the first bytes represent the size
337 sal_uInt32 nSize = 0;
338 for ( sal_Int32 nInd = 3; nInd >= 0; nInd-- )
339 nSize = ( nSize << 8 ) + (sal_uInt8)aData[nInd];
341 if ( nSize == xSeek->getLength() - 4 )
342 nHeaderOffset = 4;
345 if ( nHeaderOffset )
347 // this is either a bitmap or a metafile clipboard format, retrieve the pure stream
348 uno::Reference < io::XStream > xResult(
349 io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
350 uno::UNO_QUERY_THROW );
351 uno::Reference < io::XSeekable > xResultSeek( xResult, uno::UNO_QUERY_THROW );
352 uno::Reference < io::XOutputStream > xResultOut = xResult->getOutputStream();
353 uno::Reference < io::XInputStream > xResultIn = xResult->getInputStream();
354 if ( !xResultOut.is() || !xResultIn.is() )
355 throw uno::RuntimeException();
357 xSeek->seek( nHeaderOffset ); // header size for these formats
358 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xResultOut );
359 xResultOut->closeOutput();
360 xResultSeek->seek( 0 );
361 xSeek->seek( 0 );
363 return xResult;
366 return uno::Reference< io::XStream >();
370 void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference< io::XStream >& xTargetStream,
371 const uno::Reference< io::XStream >& xCachedVisualRepresentation )
372 throw ( uno::Exception )
374 OSL_ENSURE( xTargetStream.is() && xCachedVisualRepresentation.is(), "Invalid argumants!\n" );
376 if ( !xTargetStream.is() || !xCachedVisualRepresentation.is() )
377 throw uno::RuntimeException();
379 uno::Sequence< uno::Any > aArgs( 2 );
380 aArgs[0] <<= xTargetStream;
381 aArgs[1] <<= true; // do not create copy
383 uno::Reference< container::XNameContainer > xNameContainer(
384 m_xFactory->createInstanceWithArguments(
385 OUString( "com.sun.star.embed.OLESimpleStorage" ),
386 aArgs ),
387 uno::UNO_QUERY );
389 if ( !xNameContainer.is() )
390 throw uno::RuntimeException();
392 uno::Reference< io::XSeekable > xCachedSeek( xCachedVisualRepresentation, uno::UNO_QUERY_THROW );
393 if ( xCachedSeek.is() )
394 xCachedSeek->seek( 0 );
396 uno::Reference < io::XStream > xTempFile(
397 io::TempFile::create(comphelper::getComponentContext(m_xFactory)),
398 uno::UNO_QUERY_THROW );
400 uno::Reference< io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY_THROW );
401 uno::Reference< io::XOutputStream > xTempOutStream = xTempFile->getOutputStream();
402 if ( xTempOutStream.is() )
404 // the OlePres stream must have additional header
405 // TODO/LATER: might need to be extended in future (actually makes sense only for SO7 format)
406 uno::Reference< io::XInputStream > xInCacheStream = xCachedVisualRepresentation->getInputStream();
407 if ( !xInCacheStream.is() )
408 throw uno::RuntimeException();
410 // write 0xFFFFFFFF at the beginning
411 uno::Sequence< sal_Int8 > aData( 4 );
412 *( reinterpret_cast<sal_uInt32*>(aData.getArray()) ) = 0xFFFFFFFF;
414 xTempOutStream->writeBytes( aData );
416 // write clipboard format
417 uno::Sequence< sal_Int8 > aSigData( 2 );
418 xInCacheStream->readBytes( aSigData, 2 );
419 if ( aSigData.getLength() < 2 )
420 throw io::IOException();
422 if ( aSigData[0] == 'B' && aSigData[1] == 'M' )
424 // it's a bitmap
425 aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0;
427 else
429 // treat it as a metafile
430 aData[0] = 0x03; aData[1] = 0; aData[2] = 0; aData[3] = 0;
432 xTempOutStream->writeBytes( aData );
434 // write job related information
435 aData[0] = 0x04; aData[1] = 0; aData[2] = 0; aData[3] = 0;
436 xTempOutStream->writeBytes( aData );
438 // write aspect
439 aData[0] = 0x01; aData[1] = 0; aData[2] = 0; aData[3] = 0;
440 xTempOutStream->writeBytes( aData );
442 // write l-index
443 *( reinterpret_cast<sal_uInt32*>(aData.getArray()) ) = 0xFFFFFFFF;
444 xTempOutStream->writeBytes( aData );
446 // write adv. flags
447 aData[0] = 0x02; aData[1] = 0; aData[2] = 0; aData[3] = 0;
448 xTempOutStream->writeBytes( aData );
450 // write compression
451 *( reinterpret_cast<sal_uInt32*>(aData.getArray()) ) = 0x0;
452 xTempOutStream->writeBytes( aData );
454 // get the size
455 awt::Size aSize = getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
456 sal_Int32 nIndex = 0;
458 // write width
459 for ( nIndex = 0; nIndex < 4; nIndex++ )
461 aData[nIndex] = (sal_Int8)( aSize.Width % 0x100 );
462 aSize.Width /= 0x100;
464 xTempOutStream->writeBytes( aData );
466 // write height
467 for ( nIndex = 0; nIndex < 4; nIndex++ )
469 aData[nIndex] = (sal_Int8)( aSize.Height % 0x100 );
470 aSize.Height /= 0x100;
472 xTempOutStream->writeBytes( aData );
474 // write garbage, it will be overwritten by the size
475 xTempOutStream->writeBytes( aData );
477 // write first bytes that was used to detect the type
478 xTempOutStream->writeBytes( aSigData );
480 // write the rest of the stream
481 ::comphelper::OStorageHelper::CopyInputToOutput( xInCacheStream, xTempOutStream );
483 // write the size of the stream
484 sal_Int64 nLength = xTempSeek->getLength() - 40;
485 if ( nLength < 0 || nLength >= 0xFFFFFFFF )
487 SAL_WARN( "embeddedobj.ole", "Length is not acceptable!" );
488 return;
490 for ( sal_Int32 nInd = 0; nInd < 4; nInd++ )
492 aData[nInd] = (sal_Int8)( ( (sal_uInt64) nLength ) % 0x100 );
493 nLength /= 0x100;
495 xTempSeek->seek( 36 );
496 xTempOutStream->writeBytes( aData );
498 xTempOutStream->flush();
500 xTempSeek->seek( 0 );
501 if ( xCachedSeek.is() )
502 xCachedSeek->seek( 0 );
504 else
505 throw io::IOException(); // TODO:
507 // insert the result file as replacement image
508 OUString aCacheName = "\002OlePres000";
509 if ( xNameContainer->hasByName( aCacheName ) )
510 xNameContainer->replaceByName( aCacheName, uno::makeAny( xTempFile ) );
511 else
512 xNameContainer->insertByName( aCacheName, uno::makeAny( xTempFile ) );
514 uno::Reference< embed::XTransactedObject > xTransacted( xNameContainer, uno::UNO_QUERY );
515 if ( !xTransacted.is() )
516 throw uno::RuntimeException();
518 xTransacted->commit();
522 void OleEmbeddedObject::RemoveVisualCache_Impl( const uno::Reference< io::XStream >& xTargetStream )
523 throw ( uno::Exception )
525 OSL_ENSURE( xTargetStream.is(), "Invalid argumant!\n" );
526 if ( !xTargetStream.is() )
527 throw uno::RuntimeException();
529 uno::Sequence< uno::Any > aArgs( 2 );
530 aArgs[0] <<= xTargetStream;
531 aArgs[1] <<= true; // do not create copy
532 uno::Reference< container::XNameContainer > xNameContainer(
533 m_xFactory->createInstanceWithArguments(
534 OUString( "com.sun.star.embed.OLESimpleStorage" ),
535 aArgs ),
536 uno::UNO_QUERY );
538 if ( !xNameContainer.is() )
539 throw uno::RuntimeException();
541 for ( sal_uInt8 nInd = 0; nInd < 10; nInd++ )
543 OUString aStreamName = "\002OlePres00" + OUString::number( nInd );
544 if ( xNameContainer->hasByName( aStreamName ) )
545 xNameContainer->removeByName( aStreamName );
548 uno::Reference< embed::XTransactedObject > xTransacted( xNameContainer, uno::UNO_QUERY );
549 if ( !xTransacted.is() )
550 throw uno::RuntimeException();
552 xTransacted->commit();
556 void OleEmbeddedObject::SetVisReplInStream( bool bExists )
558 m_bVisReplInitialized = true;
559 m_bVisReplInStream = bExists;
563 bool OleEmbeddedObject::HasVisReplInStream()
565 if ( !m_bVisReplInitialized )
567 if ( m_xCachedVisualRepresentation.is() )
568 SetVisReplInStream( true );
569 else
571 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::HasVisualReplInStream, analyzing" );
573 uno::Reference< io::XInputStream > xStream;
575 OSL_ENSURE( !m_pOleComponent || !m_aTempURL.isEmpty(), "The temporary file must exist if there is a component!\n" );
576 if ( !m_aTempURL.isEmpty() )
580 // open temporary file for reading
581 uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(
582 ucb::SimpleFileAccess::create( comphelper::getComponentContext(m_xFactory) ) );
584 xStream = xTempAccess->openFileRead( m_aTempURL );
586 catch( const uno::Exception& )
590 if ( !xStream.is() )
591 xStream = m_xObjectStream->getInputStream();
593 if ( xStream.is() )
595 bool bExists = false;
597 uno::Sequence< uno::Any > aArgs( 2 );
598 aArgs[0] <<= xStream;
599 aArgs[1] <<= true; // do not create copy
600 uno::Reference< container::XNameContainer > xNameContainer(
601 m_xFactory->createInstanceWithArguments(
602 OUString( "com.sun.star.embed.OLESimpleStorage" ),
603 aArgs ),
604 uno::UNO_QUERY );
606 if ( xNameContainer.is() )
608 for ( sal_uInt8 nInd = 0; nInd < 10 && !bExists; nInd++ )
610 OUString aStreamName = "\002OlePres00" + OUString::number( nInd );
613 bExists = xNameContainer->hasByName( aStreamName );
615 catch( const uno::Exception& )
620 SetVisReplInStream( bExists );
625 return m_bVisReplInStream;
629 uno::Reference< io::XStream > OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation_Impl(
630 const uno::Reference< io::XStream >& xStream,
631 bool bAllowToRepair50 )
632 throw ()
634 uno::Reference< io::XStream > xResult;
636 if ( xStream.is() )
638 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation, retrieving" );
640 uno::Reference< container::XNameContainer > xNameContainer;
641 uno::Sequence< uno::Any > aArgs( 2 );
642 aArgs[0] <<= xStream;
643 aArgs[1] <<= true; // do not create copy
646 xNameContainer = uno::Reference< container::XNameContainer >(
647 m_xFactory->createInstanceWithArguments(
648 OUString( "com.sun.star.embed.OLESimpleStorage" ),
649 aArgs ),
650 uno::UNO_QUERY );
652 catch( const uno::Exception& )
655 if ( xNameContainer.is() )
657 for ( sal_uInt8 nInd = 0; nInd < 10; nInd++ )
659 OUString aStreamName = "\002OlePres00" + OUString::number( nInd );
660 uno::Reference< io::XStream > xCachedCopyStream;
663 if ( ( xNameContainer->getByName( aStreamName ) >>= xCachedCopyStream ) && xCachedCopyStream.is() )
665 xResult = TryToGetAcceptableFormat_Impl( xCachedCopyStream );
666 if ( xResult.is() )
667 break;
670 catch( const uno::Exception& )
673 if ( nInd == 0 )
675 // to be compatible with the old versions Ole10Native is checked after OlePress000
676 aStreamName = "\001Ole10Native";
679 if ( ( xNameContainer->getByName( aStreamName ) >>= xCachedCopyStream ) && xCachedCopyStream.is() )
681 xResult = TryToGetAcceptableFormat_Impl( xCachedCopyStream );
682 if ( xResult.is() )
683 break;
686 catch( const uno::Exception& )
693 if ( bAllowToRepair50 && !xResult.is() )
695 OUString aOrigContName( "Ole-Object" );
696 if ( xNameContainer->hasByName( aOrigContName ) )
698 uno::Reference< embed::XClassifiedObject > xClassified( xNameContainer, uno::UNO_QUERY_THROW );
699 if ( MimeConfigurationHelper::ClassIDsEqual( xClassified->getClassID(), MimeConfigurationHelper::GetSequenceClassID( SO3_OUT_CLASSID ) ) )
701 // this is an OLE object wrongly stored in 5.0 format
702 // this object must be repaired since SO7 has done it
704 uno::Reference< io::XOutputStream > xOutputStream = xStream->getOutputStream();
705 uno::Reference< io::XTruncate > xTruncate( xOutputStream, uno::UNO_QUERY_THROW );
707 uno::Reference< io::XInputStream > xOrigInputStream;
708 if ( ( xNameContainer->getByName( aOrigContName ) >>= xOrigInputStream )
709 && xOrigInputStream.is() )
711 // the provided input stream must be based on temporary medium and must be independent
712 // from the stream the storage is based on
713 uno::Reference< io::XSeekable > xOrigSeekable( xOrigInputStream, uno::UNO_QUERY );
714 if ( xOrigSeekable.is() )
715 xOrigSeekable->seek( 0 );
717 uno::Reference< lang::XComponent > xNameContDisp( xNameContainer, uno::UNO_QUERY_THROW );
718 xNameContDisp->dispose(); // free the original stream
720 xTruncate->truncate();
721 ::comphelper::OStorageHelper::CopyInputToOutput( xOrigInputStream, xOutputStream );
722 xOutputStream->flush();
724 if ( xStream == m_xObjectStream )
726 if ( !m_aTempURL.isEmpty() )
728 // this is the own stream, so the temporary URL must be cleaned if it exists
729 KillFile_Impl( m_aTempURL, m_xFactory );
730 m_aTempURL.clear();
733 #ifdef WNT
734 // retry to create the component after recovering
735 GetRidOfComponent();
739 CreateOleComponentAndLoad_Impl( NULL );
740 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
742 catch( const uno::Exception& )
744 GetRidOfComponent();
746 #endif
749 xResult = TryToRetrieveCachedVisualRepresentation_Impl( xStream, false );
755 catch( const uno::Exception& )
760 return xResult;
764 void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
765 const uno::Reference< io::XStream >& xNewObjectStream,
766 const OUString& aNewName )
768 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
770 SAL_WARN_IF( xNewObjectStream != m_xObjectStream, "embeddedobj.ole", "The streams must be the same!" );
771 return;
774 try {
775 uno::Reference< lang::XComponent > xComponent( m_xObjectStream, uno::UNO_QUERY );
776 OSL_ENSURE( !m_xObjectStream.is() || xComponent.is(), "Wrong stream implementation!" );
777 if ( xComponent.is() )
778 xComponent->dispose();
780 catch ( const uno::Exception& )
784 m_xObjectStream = xNewObjectStream;
785 m_xParentStorage = xNewParentStorage;
786 m_aEntryName = aNewName;
790 void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
791 const OUString& aNewName )
793 if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
794 return;
796 sal_Int32 nStreamMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
798 uno::Reference< io::XStream > xNewOwnStream = xNewParentStorage->openStreamElement( aNewName, nStreamMode );
799 SAL_WARN_IF( !xNewOwnStream.is(), "embeddedobj.ole", "The method can not return empty reference!" );
801 SwitchOwnPersistence( xNewParentStorage, xNewOwnStream, aNewName );
804 #ifdef WNT
806 sal_Bool OleEmbeddedObject::SaveObject_Impl()
808 sal_Bool bResult = sal_False;
810 if ( m_xClientSite.is() )
814 m_xClientSite->saveObject();
815 bResult = sal_True;
817 catch( const uno::Exception& )
822 return bResult;
826 sal_Bool OleEmbeddedObject::OnShowWindow_Impl( sal_Bool bShow )
828 ::osl::ResettableMutexGuard aGuard( m_aMutex );
830 sal_Bool bResult = sal_False;
832 SAL_WARN_IF( m_nObjectState == -1, "embeddedobj.ole", "The object has no persistence!" );
833 SAL_WARN_IF( m_nObjectState == embed::EmbedStates::LOADED, "embeddedobj.ole", "The object get OnShowWindow in loaded state!" );
834 if ( m_nObjectState == -1 || m_nObjectState == embed::EmbedStates::LOADED )
835 return sal_False;
837 // the object is either activated or deactivated
838 sal_Int32 nOldState = m_nObjectState;
839 if ( bShow && m_nObjectState == embed::EmbedStates::RUNNING )
841 m_nObjectState = embed::EmbedStates::ACTIVE;
842 m_aVerbExecutionController.ObjectIsActive();
844 aGuard.clear();
845 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
847 else if ( !bShow && m_nObjectState == embed::EmbedStates::ACTIVE )
849 m_nObjectState = embed::EmbedStates::RUNNING;
850 aGuard.clear();
851 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
854 if ( m_xClientSite.is() )
858 m_xClientSite->visibilityChanged( bShow );
859 bResult = sal_True;
861 catch( const uno::Exception& )
866 return bResult;
870 void OleEmbeddedObject::OnIconChanged_Impl()
872 // TODO/LATER: currently this notification seems to be impossible
873 // MakeEventListenerNotification_Impl( OUString( "OnIconChanged" ) );
877 void OleEmbeddedObject::OnViewChanged_Impl()
879 if ( m_bDisposed )
880 throw lang::DisposedException();
882 // For performance reasons the notification currently is ignored, STAMPIT object is the exception,
883 // it can never be active and never call SaveObject, so it is the only way to detect that it is changed
885 // ==== the STAMPIT related solution =============================
886 // the following variable is used to detect whether the object was modified during verb execution
887 m_aVerbExecutionController.ModificationNotificationIsDone();
889 // The following things are controlled by VerbExecutionController:
890 // - if the verb execution is in progress and the view is changed the object will be stored
891 // after the execution, so there is no need to send the notification.
892 // - the STAMPIT object can never be active.
893 if (m_aVerbExecutionController.CanDoNotification() &&
894 m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE &&
895 (MimeConfigurationHelper::ClassIDsEqual(m_aClassID, MimeConfigurationHelper::GetSequenceClassID(0x852ee1c9, 0x9058, 0x44ba, 0x8c, 0x6c, 0x0c, 0x5f, 0xc6, 0x6b, 0xdb, 0x8d)) ||
896 MimeConfigurationHelper::ClassIDsEqual(m_aClassID, MimeConfigurationHelper::GetSequenceClassID(0xcf1b4491, 0xbea3, 0x4c9f, 0xa7, 0x0f, 0x22, 0x1b, 0x1e, 0xca, 0xef, 0x3e)))
899 // The view is changed while the object is in running state, save the new object
900 m_xCachedVisualRepresentation = uno::Reference< io::XStream >();
901 SaveObject_Impl();
902 MakeEventListenerNotification_Impl( OUString( "OnVisAreaChanged" ) );
908 void OleEmbeddedObject::OnClosed_Impl()
910 if ( m_bDisposed )
911 throw lang::DisposedException();
913 if ( m_nObjectState != embed::EmbedStates::LOADED )
915 sal_Int32 nOldState = m_nObjectState;
916 m_nObjectState = embed::EmbedStates::LOADED;
917 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
922 OUString OleEmbeddedObject::CreateTempURLEmpty_Impl()
924 SAL_WARN_IF( !m_aTempURL.isEmpty(), "embeddedobj.ole", "The object has already the temporary file!" );
925 m_aTempURL = GetNewTempFileURL_Impl( m_xFactory );
927 return m_aTempURL;
931 OUString OleEmbeddedObject::GetTempURL_Impl()
933 if ( m_aTempURL.isEmpty() )
935 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::GetTempURL_Impl, tempfile creation" );
937 // if there is no temporary file, it will be created from the own entry
938 uno::Reference< embed::XOptimizedStorage > xOptParStorage( m_xParentStorage, uno::UNO_QUERY );
939 if ( xOptParStorage.is() )
941 m_aTempURL = GetNewFilledTempFile_Impl( xOptParStorage, m_aEntryName, m_xFactory );
943 else if ( m_xObjectStream.is() )
945 // load object from the stream
946 uno::Reference< io::XInputStream > xInStream = m_xObjectStream->getInputStream();
947 if ( !xInStream.is() )
948 throw io::IOException(); // TODO: access denied
950 m_aTempURL = GetNewFilledTempFile_Impl( xInStream, m_xFactory );
954 return m_aTempURL;
958 void OleEmbeddedObject::CreateOleComponent_Impl( OleComponent* pOleComponent )
960 if ( !m_pOleComponent )
962 m_pOleComponent = pOleComponent ? pOleComponent : new OleComponent( m_xFactory, this );
963 m_pOleComponent->acquire(); // TODO: needs holder?
965 if ( !m_xClosePreventer.is() )
966 m_xClosePreventer = uno::Reference< util::XCloseListener >(
967 static_cast< ::cppu::OWeakObject* >( new OClosePreventer ),
968 uno::UNO_QUERY );
970 m_pOleComponent->addCloseListener( m_xClosePreventer );
975 void OleEmbeddedObject::CreateOleComponentAndLoad_Impl( OleComponent* pOleComponent )
977 if ( !m_pOleComponent )
979 if ( !m_xObjectStream.is() )
980 throw uno::RuntimeException();
982 CreateOleComponent_Impl( pOleComponent );
984 // after the loading the object can appear as a link
985 // will be detected later by olecomponent
987 GetTempURL_Impl();
988 if ( m_aTempURL.isEmpty() )
989 throw uno::RuntimeException(); // TODO
991 m_pOleComponent->LoadEmbeddedObject( m_aTempURL );
996 void OleEmbeddedObject::CreateOleComponentFromClipboard_Impl( OleComponent* pOleComponent )
998 if ( !m_pOleComponent )
1000 if ( !m_xObjectStream.is() )
1001 throw uno::RuntimeException();
1003 CreateOleComponent_Impl( pOleComponent );
1005 // after the loading the object can appear as a link
1006 // will be detected later by olecomponent
1007 m_pOleComponent->CreateObjectFromClipboard();
1012 uno::Reference< io::XOutputStream > OleEmbeddedObject::GetStreamForSaving()
1014 if ( !m_xObjectStream.is() )
1015 throw uno::RuntimeException(); //TODO:
1017 uno::Reference< io::XOutputStream > xOutStream = m_xObjectStream->getOutputStream();
1018 if ( !xOutStream.is() )
1019 throw io::IOException(); //TODO: access denied
1021 uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY );
1022 if ( !xTruncate.is() )
1023 throw uno::RuntimeException(); //TODO:
1025 xTruncate->truncate();
1027 return xOutStream;
1031 void OleEmbeddedObject::StoreObjectToStream( uno::Reference< io::XOutputStream > xOutStream )
1032 throw ( uno::Exception )
1034 // this method should be used only on windows
1035 if ( m_pOleComponent )
1036 m_pOleComponent->StoreOwnTmpIfNecessary();
1038 // now all the changes should be in temporary location
1039 if ( m_aTempURL.isEmpty() )
1040 throw uno::RuntimeException();
1042 // open temporary file for reading
1043 uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(
1044 ucb::SimpleFileAccess::create( comphelper::getComponentContext(m_xFactory) ) );
1046 uno::Reference< io::XInputStream > xTempInStream = xTempAccess->openFileRead( m_aTempURL );
1047 SAL_WARN_IF( !xTempInStream.is(), "embeddedobj.ole", "The object's temporary file can not be reopened for reading!" );
1049 // TODO: use bStoreVisReplace
1051 if ( xTempInStream.is() )
1053 // write all the contents to XOutStream
1054 uno::Reference< io::XTruncate > xTrunc( xOutStream, uno::UNO_QUERY );
1055 if ( !xTrunc.is() )
1056 throw uno::RuntimeException(); //TODO:
1058 xTrunc->truncate();
1060 ::comphelper::OStorageHelper::CopyInputToOutput( xTempInStream, xOutStream );
1062 else
1063 throw io::IOException(); // TODO:
1065 // TODO: should the view replacement be in the stream ???
1066 // probably it must be specified on storing
1068 #endif
1070 void OleEmbeddedObject::StoreToLocation_Impl(
1071 const uno::Reference< embed::XStorage >& xStorage,
1072 const OUString& sEntName,
1073 const uno::Sequence< beans::PropertyValue >& lObjArgs,
1074 bool bSaveAs )
1075 throw ( uno::Exception )
1077 // TODO: use lObjArgs
1078 // TODO: exchange StoreVisualReplacement by SO file format version?
1080 if ( m_nObjectState == -1 )
1082 // the object is still not loaded
1083 throw embed::WrongStateException( "Can't store object without persistence!",
1084 static_cast< ::cppu::OWeakObject* >(this) );
1087 if ( m_bWaitSaveCompleted )
1088 throw embed::WrongStateException(
1089 "The object waits for saveCompleted() call!",
1090 static_cast< ::cppu::OWeakObject* >(this) );
1092 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStream.is(), "The object has no valid persistence!\n" );
1094 bool bVisReplIsStored = false;
1096 bool bTryOptimization = false;
1097 bool bStoreVis = m_bStoreVisRepl;
1098 uno::Reference< io::XStream > xCachedVisualRepresentation;
1099 for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1101 if ( lObjArgs[nInd].Name == "StoreVisualReplacement" )
1102 lObjArgs[nInd].Value >>= bStoreVis;
1103 else if ( lObjArgs[nInd].Name == "VisualReplacement" )
1104 lObjArgs[nInd].Value >>= xCachedVisualRepresentation;
1105 else if ( lObjArgs[nInd].Name == "CanTryOptimization" )
1106 lObjArgs[nInd].Value >>= bTryOptimization;
1109 // ignore visual representation provided from outside if it should not be stored
1110 if ( !bStoreVis )
1111 xCachedVisualRepresentation = uno::Reference< io::XStream >();
1113 if ( bStoreVis && !HasVisReplInStream() && !xCachedVisualRepresentation.is() )
1114 throw io::IOException(); // TODO: there is no cached visual representation and nothing is provided from outside
1116 // if the representation is provided from outside it should be copied to a local stream
1117 bool bNeedLocalCache = xCachedVisualRepresentation.is();
1119 uno::Reference< io::XStream > xTargetStream;
1121 bool bStoreLoaded = false;
1122 if ( m_nObjectState == embed::EmbedStates::LOADED
1123 #ifdef WNT
1124 // if the object was NOT modified after storing it can be just copied
1125 // as if it was in loaded state
1126 || ( m_pOleComponent && !m_pOleComponent->IsDirty() )
1127 #endif
1130 bool bOptimizedCopyingDone = false;
1132 if ( bTryOptimization && bStoreVis == HasVisReplInStream() )
1136 uno::Reference< embed::XOptimizedStorage > xSourceOptStor( m_xParentStorage, uno::UNO_QUERY_THROW );
1137 uno::Reference< embed::XOptimizedStorage > xTargetOptStor( xStorage, uno::UNO_QUERY_THROW );
1138 xSourceOptStor->copyElementDirectlyTo( m_aEntryName, xTargetOptStor, sEntName );
1139 bOptimizedCopyingDone = true;
1141 catch( const uno::Exception& )
1146 if ( !bOptimizedCopyingDone )
1148 // if optimized copying fails a normal one should be tried
1149 m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
1152 // the locally retrieved representation is always preferable
1153 // since the object is in loaded state the representation is unchanged
1154 if ( m_xCachedVisualRepresentation.is() )
1156 xCachedVisualRepresentation = m_xCachedVisualRepresentation;
1157 bNeedLocalCache = false;
1160 bVisReplIsStored = HasVisReplInStream();
1161 bStoreLoaded = true;
1163 #ifdef WNT
1164 else if ( m_pOleComponent )
1166 xTargetStream =
1167 xStorage->openStreamElement( sEntName, embed::ElementModes::READWRITE );
1168 if ( !xTargetStream.is() )
1169 throw io::IOException(); //TODO: access denied
1171 SetStreamMediaType_Impl( xTargetStream, OUString( "application/vnd.sun.star.oleobject" ));
1172 uno::Reference< io::XOutputStream > xOutStream = xTargetStream->getOutputStream();
1173 if ( !xOutStream.is() )
1174 throw io::IOException(); //TODO: access denied
1176 StoreObjectToStream( xOutStream );
1177 bVisReplIsStored = sal_True;
1179 if ( bSaveAs )
1181 // no need to do it on StoreTo since in this case the replacement is in the stream
1182 // and there is no need to cache it even if it is thrown away because the object
1183 // is not changed by StoreTo action
1185 uno::Reference< io::XStream > xTmpCVRepresentation =
1186 TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
1188 // the locally retrieved representation is always preferable
1189 if ( xTmpCVRepresentation.is() )
1191 xCachedVisualRepresentation = xTmpCVRepresentation;
1192 bNeedLocalCache = sal_False;
1196 #endif
1197 else
1199 throw io::IOException(); // TODO
1202 if ( !xTargetStream.is() )
1204 xTargetStream =
1205 xStorage->openStreamElement( sEntName, embed::ElementModes::READWRITE );
1206 if ( !xTargetStream.is() )
1207 throw io::IOException(); //TODO: access denied
1210 LetCommonStoragePassBeUsed_Impl( xTargetStream );
1212 if ( bStoreVis != bVisReplIsStored )
1214 if ( bStoreVis )
1216 if ( !xCachedVisualRepresentation.is() )
1217 xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
1219 SAL_WARN_IF( !xCachedVisualRepresentation.is(), "embeddedobj.ole", "No representation is available!" );
1221 // the following copying will be done in case it is SaveAs anyway
1222 // if it is not SaveAs the seekable access is not required currently
1223 // TODO/LATER: may be required in future
1224 if ( bSaveAs )
1226 uno::Reference< io::XSeekable > xCachedSeek( xCachedVisualRepresentation, uno::UNO_QUERY );
1227 if ( !xCachedSeek.is() )
1229 xCachedVisualRepresentation
1230 = GetNewFilledTempStream_Impl( xCachedVisualRepresentation->getInputStream() );
1231 bNeedLocalCache = false;
1235 InsertVisualCache_Impl( xTargetStream, xCachedVisualRepresentation );
1237 else
1239 // the removed representation could be cached by this method
1240 if ( !xCachedVisualRepresentation.is() )
1241 xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
1243 RemoveVisualCache_Impl( xTargetStream );
1247 if ( bSaveAs )
1249 m_bWaitSaveCompleted = true;
1250 m_xNewObjectStream = xTargetStream;
1251 m_xNewParentStorage = xStorage;
1252 m_aNewEntryName = sEntName;
1253 m_bNewVisReplInStream = bStoreVis;
1254 m_bStoreLoaded = bStoreLoaded;
1256 if ( xCachedVisualRepresentation.is() )
1258 if ( bNeedLocalCache )
1259 m_xNewCachedVisRepl = GetNewFilledTempStream_Impl( xCachedVisualRepresentation->getInputStream() );
1260 else
1261 m_xNewCachedVisRepl = xCachedVisualRepresentation;
1264 // TODO: register listeners for storages above, in case they are disposed
1265 // an exception will be thrown on saveCompleted( true )
1267 else
1269 uno::Reference< lang::XComponent > xComp( xTargetStream, uno::UNO_QUERY );
1270 if ( xComp.is() )
1272 try {
1273 xComp->dispose();
1274 } catch( const uno::Exception& )
1282 void SAL_CALL OleEmbeddedObject::setPersistentEntry(
1283 const uno::Reference< embed::XStorage >& xStorage,
1284 const OUString& sEntName,
1285 sal_Int32 nEntryConnectionMode,
1286 const uno::Sequence< beans::PropertyValue >& lArguments,
1287 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1288 throw ( lang::IllegalArgumentException,
1289 embed::WrongStateException,
1290 io::IOException,
1291 uno::Exception,
1292 uno::RuntimeException, std::exception )
1294 // begin wrapping related part ====================
1295 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1296 if ( xWrappedObject.is() )
1298 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1299 xWrappedObject->setPersistentEntry( xStorage, sEntName, nEntryConnectionMode, lArguments, lObjArgs );
1300 return;
1302 // end wrapping related part ====================
1304 // TODO: use lObjArgs
1306 // the type of the object must be already set
1307 // a kind of typedetection should be done in the factory;
1308 // the only exception is object initialized from a stream,
1309 // the class ID will be detected from the stream
1311 ::osl::MutexGuard aGuard( m_aMutex );
1312 if ( m_bDisposed )
1313 throw lang::DisposedException(); // TODO
1315 if ( !xStorage.is() )
1316 throw lang::IllegalArgumentException( "No parent storage is provided!",
1317 static_cast< ::cppu::OWeakObject* >(this),
1318 1 );
1320 if ( sEntName.isEmpty() )
1321 throw lang::IllegalArgumentException( "Empty element name is provided!",
1322 static_cast< ::cppu::OWeakObject* >(this),
1323 2 );
1325 // May be LOADED should be forbidden here ???
1326 if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1327 && ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) )
1329 // if the object is not loaded
1330 // it can not get persistent representation without initialization
1332 // if the object is loaded
1333 // it can switch persistent representation only without initialization
1335 throw embed::WrongStateException(
1336 "Can't change persistent representation of activated object!",
1337 static_cast< ::cppu::OWeakObject* >(this) );
1340 if ( m_bWaitSaveCompleted )
1342 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1343 saveCompleted( ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) ) );
1344 else
1345 throw embed::WrongStateException(
1346 "The object waits for saveCompleted() call!",
1347 static_cast< ::cppu::OWeakObject* >(this) );
1350 uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
1351 if ( !xNameAccess.is() )
1352 throw uno::RuntimeException(); //TODO
1354 // detect entry existence
1355 bool bElExists = xNameAccess->hasByName( sEntName );
1357 m_bReadOnly = false;
1358 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1359 if ( lArguments[nInd].Name == "ReadOnly" )
1360 lArguments[nInd].Value >>= m_bReadOnly;
1362 #ifdef WNT
1363 sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
1364 #endif
1366 SwitchOwnPersistence( xStorage, sEntName );
1368 for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1369 if ( lObjArgs[nInd].Name == "StoreVisualReplacement" )
1370 lObjArgs[nInd].Value >>= m_bStoreVisRepl;
1372 #ifdef WNT
1373 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT )
1375 if ( m_bFromClipboard )
1377 // the object should be initialized from clipboard
1378 // inpossibility to initialize the object means error here
1379 CreateOleComponentFromClipboard_Impl( NULL );
1380 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
1381 m_pOleComponent->RunObject();
1382 m_nObjectState = embed::EmbedStates::RUNNING;
1384 else if ( bElExists )
1386 // load object from the stream
1387 // after the loading the object can appear as a link
1388 // will be detected by olecomponent
1391 CreateOleComponentAndLoad_Impl( NULL );
1392 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
1394 catch( const uno::Exception& )
1396 // TODO/LATER: detect classID of the object if possible
1397 // means that the object inprocess server could not be successfully instantiated
1398 GetRidOfComponent();
1401 m_nObjectState = embed::EmbedStates::LOADED;
1403 else
1405 // create a new object
1406 CreateOleComponent_Impl();
1407 m_pOleComponent->CreateNewEmbeddedObject( m_aClassID );
1408 m_pOleComponent->RunObject();
1409 m_nObjectState = embed::EmbedStates::RUNNING;
1412 else
1414 if ( ( nStorageMode & embed::ElementModes::READWRITE ) != embed::ElementModes::READWRITE )
1415 throw io::IOException();
1417 if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1419 // the document just already changed its stream to store to;
1420 // the links to OLE documents switch their persistence in the same way
1421 // as normal embedded objects
1423 else if ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT )
1425 // create a new object, that will be stored in specified stream
1426 CreateOleComponent_Impl();
1428 m_pOleComponent->CreateNewEmbeddedObject( m_aClassID );
1429 m_pOleComponent->RunObject();
1430 m_nObjectState = embed::EmbedStates::RUNNING;
1432 else if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
1434 // use URL ( may be content or stream later ) from MediaDescriptor to initialize object
1435 OUString aURL;
1436 for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1437 if ( lArguments[nInd].Name == "URL" )
1438 lArguments[nInd].Value >>= aURL;
1440 if ( aURL.isEmpty() )
1441 throw lang::IllegalArgumentException(
1442 "Empty URL is provided in the media descriptor!",
1443 static_cast< ::cppu::OWeakObject* >(this),
1444 4 );
1446 CreateOleComponent_Impl();
1448 // TODO: the m_bIsLink value must be set already
1449 if ( !m_bIsLink )
1450 m_pOleComponent->CreateObjectFromFile( aURL );
1451 else
1452 m_pOleComponent->CreateLinkFromFile( aURL );
1454 m_pOleComponent->RunObject();
1455 m_aClassID = m_pOleComponent->GetCLSID(); // was not set during consruction
1457 m_nObjectState = embed::EmbedStates::RUNNING;
1459 //else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT )
1461 //TODO:
1463 else
1464 throw lang::IllegalArgumentException( "Wrong connection mode is provided!",
1465 static_cast< ::cppu::OWeakObject* >(this),
1466 3 );
1468 #else
1469 // On unix the ole object can not do anything except storing itself somewere
1470 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT && bElExists )
1472 // TODO/LATER: detect classID of the object
1473 // can be a real problem for the links
1475 m_nObjectState = embed::EmbedStates::LOADED;
1477 else if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1479 // do nothing, the object has already switched it's persistence
1481 else
1482 throw lang::IllegalArgumentException( "Wrong connection mode is provided!",
1483 static_cast< ::cppu::OWeakObject* >(this),
1484 3 );
1486 #endif
1490 void SAL_CALL OleEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage,
1491 const OUString& sEntName,
1492 const uno::Sequence< beans::PropertyValue >& lArguments,
1493 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1494 throw ( lang::IllegalArgumentException,
1495 embed::WrongStateException,
1496 io::IOException,
1497 uno::Exception,
1498 uno::RuntimeException, std::exception )
1500 // begin wrapping related part ====================
1501 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1502 if ( xWrappedObject.is() )
1504 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1505 xWrappedObject->storeToEntry( xStorage, sEntName, lArguments, lObjArgs );
1506 return;
1508 // end wrapping related part ====================
1510 ::osl::MutexGuard aGuard( m_aMutex );
1511 if ( m_bDisposed )
1512 throw lang::DisposedException(); // TODO
1514 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
1516 StoreToLocation_Impl( xStorage, sEntName, lObjArgs, false );
1518 // TODO: should the listener notification be done?
1522 void SAL_CALL OleEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage,
1523 const OUString& sEntName,
1524 const uno::Sequence< beans::PropertyValue >& lArguments,
1525 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1526 throw ( lang::IllegalArgumentException,
1527 embed::WrongStateException,
1528 io::IOException,
1529 uno::Exception,
1530 uno::RuntimeException, std::exception )
1532 // begin wrapping related part ====================
1533 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1534 if ( xWrappedObject.is() )
1536 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1537 xWrappedObject->storeAsEntry( xStorage, sEntName, lArguments, lObjArgs );
1538 return;
1540 // end wrapping related part ====================
1542 ::osl::MutexGuard aGuard( m_aMutex );
1543 if ( m_bDisposed )
1544 throw lang::DisposedException(); // TODO
1546 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
1548 StoreToLocation_Impl( xStorage, sEntName, lObjArgs, true );
1550 // TODO: should the listener notification be done here or in saveCompleted?
1554 void SAL_CALL OleEmbeddedObject::saveCompleted( sal_Bool bUseNew )
1555 throw ( embed::WrongStateException,
1556 uno::Exception,
1557 uno::RuntimeException, std::exception )
1559 // begin wrapping related part ====================
1560 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1561 if ( xWrappedObject.is() )
1563 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1564 xWrappedObject->saveCompleted( bUseNew );
1565 return;
1567 // end wrapping related part ====================
1569 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1570 if ( m_bDisposed )
1571 throw lang::DisposedException(); // TODO
1573 if ( m_nObjectState == -1 )
1575 // the object is still not loaded
1576 throw embed::WrongStateException( "Can't store object without persistence!",
1577 static_cast< ::cppu::OWeakObject* >(this) );
1580 // it is allowed to call saveCompleted( false ) for nonstored objects
1581 if ( !m_bWaitSaveCompleted && !bUseNew )
1582 return;
1584 SAL_WARN_IF( !m_bWaitSaveCompleted, "embeddedobj.ole", "Unexpected saveCompleted() call!\n" );
1585 if ( !m_bWaitSaveCompleted )
1586 throw io::IOException(); // TODO: illegal call
1588 OSL_ENSURE( m_xNewObjectStream.is() && m_xNewParentStorage.is() , "Internal object information is broken!\n" );
1589 if ( !m_xNewObjectStream.is() || !m_xNewParentStorage.is() )
1590 throw uno::RuntimeException(); // TODO: broken internal information
1592 if ( bUseNew )
1594 SwitchOwnPersistence( m_xNewParentStorage, m_xNewObjectStream, m_aNewEntryName );
1595 m_bStoreVisRepl = m_bNewVisReplInStream;
1596 SetVisReplInStream( m_bNewVisReplInStream );
1597 m_xCachedVisualRepresentation = m_xNewCachedVisRepl;
1599 else
1601 // close remembered stream
1602 try {
1603 uno::Reference< lang::XComponent > xComponent( m_xNewObjectStream, uno::UNO_QUERY );
1604 SAL_WARN_IF( !xComponent.is(), "embeddedobj.ole", "Wrong storage implementation!" );
1605 if ( xComponent.is() )
1606 xComponent->dispose();
1608 catch ( const uno::Exception& )
1613 bool bStoreLoaded = m_bStoreLoaded;
1615 m_xNewObjectStream = uno::Reference< io::XStream >();
1616 m_xNewParentStorage = uno::Reference< embed::XStorage >();
1617 m_aNewEntryName.clear();
1618 m_bWaitSaveCompleted = false;
1619 m_bNewVisReplInStream = false;
1620 m_xNewCachedVisRepl = uno::Reference< io::XStream >();
1621 m_bStoreLoaded = false;
1623 if ( bUseNew && m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded
1624 && m_nObjectState != embed::EmbedStates::LOADED )
1626 // the object replacement image should be updated, so the cached size as well
1627 m_bHasCachedSize = false;
1630 // the call will cache the size in case of success
1631 // probably it might need to be done earlier, while the object is in active state
1632 getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1634 catch( const uno::Exception& )
1638 aGuard.clear();
1639 if ( bUseNew )
1641 MakeEventListenerNotification_Impl( OUString( "OnSaveAsDone" ));
1643 // the object can be changed only on windows
1644 // the notification should be done only if the object is not in loaded state
1645 if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
1647 MakeEventListenerNotification_Impl( OUString( "OnVisAreaChanged" ));
1653 sal_Bool SAL_CALL OleEmbeddedObject::hasEntry()
1654 throw ( embed::WrongStateException,
1655 uno::RuntimeException, std::exception )
1657 // begin wrapping related part ====================
1658 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1659 if ( xWrappedObject.is() )
1661 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1662 return xWrappedObject->hasEntry();
1664 // end wrapping related part ====================
1666 ::osl::MutexGuard aGuard( m_aMutex );
1667 if ( m_bDisposed )
1668 throw lang::DisposedException(); // TODO
1670 if ( m_bWaitSaveCompleted )
1671 throw embed::WrongStateException(
1672 "The object waits for saveCompleted() call!",
1673 static_cast< ::cppu::OWeakObject* >(this) );
1675 if ( m_xObjectStream.is() )
1676 return sal_True;
1678 return sal_False;
1682 OUString SAL_CALL OleEmbeddedObject::getEntryName()
1683 throw ( embed::WrongStateException,
1684 uno::RuntimeException, std::exception )
1686 // begin wrapping related part ====================
1687 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1688 if ( xWrappedObject.is() )
1690 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1691 return xWrappedObject->getEntryName();
1693 // end wrapping related part ====================
1695 ::osl::MutexGuard aGuard( m_aMutex );
1696 if ( m_bDisposed )
1697 throw lang::DisposedException(); // TODO
1699 if ( m_nObjectState == -1 )
1701 // the object is still not loaded
1702 throw embed::WrongStateException( "The object persistence is not initialized!",
1703 static_cast< ::cppu::OWeakObject* >(this) );
1706 if ( m_bWaitSaveCompleted )
1707 throw embed::WrongStateException(
1708 "The object waits for saveCompleted() call!",
1709 static_cast< ::cppu::OWeakObject* >(this) );
1711 return m_aEntryName;
1716 void SAL_CALL OleEmbeddedObject::storeOwn()
1717 throw ( embed::WrongStateException,
1718 io::IOException,
1719 uno::Exception,
1720 uno::RuntimeException, std::exception )
1722 // begin wrapping related part ====================
1723 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1724 if ( xWrappedObject.is() )
1726 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1727 xWrappedObject->storeOwn();
1728 return;
1730 // end wrapping related part ====================
1732 // during switching from Activated to Running and from Running to Loaded states the object will
1733 // ask container to store the object, the container has to make decision
1734 // to do so or not
1736 ::osl::ResettableMutexGuard aGuard( m_aMutex );
1737 if ( m_bDisposed )
1738 throw lang::DisposedException(); // TODO
1740 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
1742 if ( m_nObjectState == -1 )
1744 // the object is still not loaded
1745 throw embed::WrongStateException( "Can't store object without persistence!",
1746 static_cast< ::cppu::OWeakObject* >(this) );
1749 if ( m_bWaitSaveCompleted )
1750 throw embed::WrongStateException(
1751 "The object waits for saveCompleted() call!",
1752 static_cast< ::cppu::OWeakObject* >(this) );
1754 if ( m_bReadOnly )
1755 throw io::IOException(); // TODO: access denied
1757 LetCommonStoragePassBeUsed_Impl( m_xObjectStream );
1759 bool bStoreLoaded = true;
1761 #ifdef WNT
1762 if ( m_nObjectState != embed::EmbedStates::LOADED && m_pOleComponent && m_pOleComponent->IsDirty() )
1764 bStoreLoaded = sal_False;
1766 OSL_ENSURE( m_xParentStorage.is() && m_xObjectStream.is(), "The object has no valid persistence!\n" );
1768 if ( !m_xObjectStream.is() )
1769 throw io::IOException(); //TODO: access denied
1771 SetStreamMediaType_Impl( m_xObjectStream, OUString( "application/vnd.sun.star.oleobject" ));
1772 uno::Reference< io::XOutputStream > xOutStream = m_xObjectStream->getOutputStream();
1773 if ( !xOutStream.is() )
1774 throw io::IOException(); //TODO: access denied
1776 // TODO: does this work for links too?
1777 StoreObjectToStream( GetStreamForSaving() );
1779 // the replacement is changed probably, and it must be in the object stream
1780 if ( !m_pOleComponent->IsWorkaroundActive() )
1781 m_xCachedVisualRepresentation = uno::Reference< io::XStream >();
1782 SetVisReplInStream( sal_True );
1784 #endif
1786 if ( m_bStoreVisRepl != HasVisReplInStream() )
1788 if ( m_bStoreVisRepl )
1790 // the m_xCachedVisualRepresentation must be set or it should be already stored
1791 if ( m_xCachedVisualRepresentation.is() )
1792 InsertVisualCache_Impl( m_xObjectStream, m_xCachedVisualRepresentation );
1793 else
1795 m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream );
1796 SAL_WARN_IF( !m_xCachedVisualRepresentation.is(), "embeddedobj.ole", "No representation is available!" );
1799 else
1801 if ( !m_xCachedVisualRepresentation.is() )
1802 m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream );
1803 RemoveVisualCache_Impl( m_xObjectStream );
1806 SetVisReplInStream( m_bStoreVisRepl );
1809 if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
1811 // the object replacement image should be updated, so the cached size as well
1812 m_bHasCachedSize = false;
1815 // the call will cache the size in case of success
1816 // probably it might need to be done earlier, while the object is in active state
1817 getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1819 catch( const uno::Exception& )
1823 aGuard.clear();
1825 MakeEventListenerNotification_Impl( OUString( "OnSaveDone" ));
1827 // the object can be changed only on Windows
1828 // the notification should be done only if the object is not in loaded state
1829 if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
1830 MakeEventListenerNotification_Impl( OUString( "OnVisAreaChanged" ));
1834 sal_Bool SAL_CALL OleEmbeddedObject::isReadonly()
1835 throw ( embed::WrongStateException,
1836 uno::RuntimeException, std::exception )
1838 // begin wrapping related part ====================
1839 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1840 if ( xWrappedObject.is() )
1842 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1843 return xWrappedObject->isReadonly();
1845 // end wrapping related part ====================
1847 ::osl::MutexGuard aGuard( m_aMutex );
1848 if ( m_bDisposed )
1849 throw lang::DisposedException(); // TODO
1851 if ( m_nObjectState == -1 )
1853 // the object is still not loaded
1854 throw embed::WrongStateException( "The object persistence is not initialized!",
1855 static_cast< ::cppu::OWeakObject* >(this) );
1858 if ( m_bWaitSaveCompleted )
1859 throw embed::WrongStateException(
1860 "The object waits for saveCompleted() call!",
1861 static_cast< ::cppu::OWeakObject* >(this) );
1863 return m_bReadOnly;
1867 void SAL_CALL OleEmbeddedObject::reload(
1868 const uno::Sequence< beans::PropertyValue >& lArguments,
1869 const uno::Sequence< beans::PropertyValue >& lObjArgs )
1870 throw ( lang::IllegalArgumentException,
1871 embed::WrongStateException,
1872 io::IOException,
1873 uno::Exception,
1874 uno::RuntimeException, std::exception )
1876 // begin wrapping related part ====================
1877 uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1878 if ( xWrappedObject.is() )
1880 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1881 xWrappedObject->reload( lArguments, lObjArgs );
1882 return;
1884 // end wrapping related part ====================
1886 // TODO: use lObjArgs
1888 ::osl::MutexGuard aGuard( m_aMutex );
1889 if ( m_bDisposed )
1890 throw lang::DisposedException(); // TODO
1892 if ( m_nObjectState == -1 )
1894 // the object is still not loaded
1895 throw embed::WrongStateException( "The object persistence is not initialized!",
1896 static_cast< ::cppu::OWeakObject* >(this) );
1899 if ( m_bWaitSaveCompleted )
1900 throw embed::WrongStateException(
1901 "The object waits for saveCompleted() call!",
1902 static_cast< ::cppu::OWeakObject* >(this) );
1904 // TODO:
1905 // throw away current document
1906 // load new document from current storage
1907 // use meaningfull part of lArguments
1911 void SAL_CALL OleEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage,
1912 const OUString& sEntName )
1913 throw ( lang::IllegalArgumentException,
1914 embed::WrongStateException,
1915 io::IOException,
1916 uno::Exception,
1917 uno::RuntimeException, std::exception )
1919 // begin wrapping related part ====================
1920 uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
1921 if ( xWrappedObject.is() )
1923 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1924 xWrappedObject->breakLink( xStorage, sEntName );
1925 return;
1927 // end wrapping related part ====================
1929 ::osl::MutexGuard aGuard( m_aMutex );
1930 if ( m_bDisposed )
1931 throw lang::DisposedException(); // TODO
1933 if ( !xStorage.is() )
1934 throw lang::IllegalArgumentException( "No parent storage is provided!",
1935 static_cast< ::cppu::OWeakObject* >(this),
1936 1 );
1938 if ( sEntName.isEmpty() )
1939 throw lang::IllegalArgumentException( "Empty element name is provided!",
1940 static_cast< ::cppu::OWeakObject* >(this),
1941 2 );
1943 // TODO: The object must be at least in Running state;
1944 if ( !m_bIsLink || m_nObjectState == -1 || !m_pOleComponent )
1946 // it must be a linked initialized object
1947 throw embed::WrongStateException(
1948 "The object is not a valid linked object!",
1949 static_cast< ::cppu::OWeakObject* >(this) );
1952 if ( m_bReadOnly )
1953 throw io::IOException(); // TODO: Access denied
1955 if ( m_bWaitSaveCompleted )
1956 throw embed::WrongStateException(
1957 "The object waits for saveCompleted() call!",
1958 static_cast< ::cppu::OWeakObject* >(this) );
1961 #ifdef WNT
1962 if ( m_pOleComponent )
1964 // TODO: create an object based on the link
1966 // disconnect the old temporary URL
1967 OUString aOldTempURL = m_aTempURL;
1968 m_aTempURL.clear();
1970 OleComponent* pNewOleComponent = new OleComponent( m_xFactory, this );
1971 try {
1972 pNewOleComponent->InitEmbeddedCopyOfLink( m_pOleComponent );
1974 catch ( const uno::Exception& )
1976 delete pNewOleComponent;
1977 if ( !m_aTempURL.isEmpty() )
1978 KillFile_Impl( m_aTempURL, m_xFactory );
1979 m_aTempURL = aOldTempURL;
1980 throw;
1983 try {
1984 GetRidOfComponent();
1986 catch( const uno::Exception& )
1988 delete pNewOleComponent;
1989 if ( !m_aTempURL.isEmpty() )
1990 KillFile_Impl( m_aTempURL, m_xFactory );
1991 m_aTempURL = aOldTempURL;
1992 throw;
1995 KillFile_Impl( aOldTempURL, m_xFactory );
1997 CreateOleComponent_Impl( pNewOleComponent );
1999 if ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) )
2000 SwitchOwnPersistence( xStorage, sEntName );
2002 if ( m_nObjectState != embed::EmbedStates::LOADED )
2004 // TODO: should we activate the new object if the link was activated?
2006 sal_Int32 nTargetState = m_nObjectState;
2007 m_nObjectState = embed::EmbedStates::LOADED;
2009 if ( m_nObjectState == embed::EmbedStates::RUNNING )
2010 m_pOleComponent->RunObject(); // the object already was in running state, the server must be installed
2011 else // m_nObjectState == embed::EmbedStates::ACTIVE
2013 m_pOleComponent->RunObject(); // the object already was in running state, the server must be installed
2014 m_pOleComponent->ExecuteVerb( embed::EmbedVerbs::MS_OLEVERB_OPEN );
2017 m_nObjectState = nTargetState;
2020 m_bIsLink = sal_False;
2021 m_aLinkURL.clear();
2023 else
2024 #endif
2026 throw io::IOException(); //TODO:
2031 sal_Bool SAL_CALL OleEmbeddedObject::isLink()
2032 throw ( embed::WrongStateException,
2033 uno::RuntimeException, std::exception )
2035 // begin wrapping related part ====================
2036 uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
2037 if ( xWrappedObject.is() )
2039 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2040 return xWrappedObject->isLink();
2042 // end wrapping related part ====================
2044 ::osl::MutexGuard aGuard( m_aMutex );
2045 if ( m_bDisposed )
2046 throw lang::DisposedException(); // TODO
2048 return m_bIsLink;
2052 OUString SAL_CALL OleEmbeddedObject::getLinkURL()
2053 throw ( embed::WrongStateException,
2054 uno::Exception,
2055 uno::RuntimeException, std::exception )
2057 // begin wrapping related part ====================
2058 uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
2059 if ( xWrappedObject.is() )
2061 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2062 return xWrappedObject->getLinkURL();
2064 // end wrapping related part ====================
2066 ::osl::MutexGuard aGuard( m_aMutex );
2067 if ( m_bDisposed )
2068 throw lang::DisposedException(); // TODO
2070 if ( m_bWaitSaveCompleted )
2071 throw embed::WrongStateException(
2072 "The object waits for saveCompleted() call!",
2073 static_cast< ::cppu::OWeakObject* >(this) );
2075 if ( !m_bIsLink )
2076 throw embed::WrongStateException(
2077 "The object is not a link object!",
2078 static_cast< ::cppu::OWeakObject* >(this) );
2080 // TODO: probably the link URL can be retrieved from OLE
2082 return m_aLinkURL;
2085 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */