1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <com/sun/star/embed/EmbedStates.hpp>
22 #include <com/sun/star/embed/EmbedVerbs.hpp>
23 #include <com/sun/star/embed/EntryInitModes.hpp>
24 #include <com/sun/star/embed/XStorage.hpp>
25 #include <com/sun/star/embed/XTransactedObject.hpp>
26 #include <com/sun/star/embed/ElementModes.hpp>
27 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
28 #include <com/sun/star/embed/Aspects.hpp>
29 #include <com/sun/star/embed/XOptimizedStorage.hpp>
30 #include <com/sun/star/lang/XComponent.hpp>
31 #include <com/sun/star/lang/DisposedException.hpp>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/container/XNameContainer.hpp>
34 #include <com/sun/star/io/TempFile.hpp>
35 #include <com/sun/star/io/XSeekable.hpp>
36 #include <com/sun/star/io/XTruncate.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
40 #include <comphelper/processfactory.hxx>
41 #include <comphelper/storagehelper.hxx>
42 #include <comphelper/mimeconfighelper.hxx>
43 #include <comphelper/classids.hxx>
44 #include <osl/thread.hxx>
46 #include <olecomponent.hxx>
47 #include <closepreventer.hxx>
49 using namespace ::com::sun::star
;
50 using namespace ::comphelper
;
52 //-------------------------------------------------------------------------
53 sal_Bool
KillFile_Impl( const OUString
& aURL
, const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
58 sal_Bool bRet
= sal_False
;
62 uno::Reference
< ucb::XSimpleFileAccess3
> xAccess(
63 ucb::SimpleFileAccess::create( comphelper::getComponentContext(xFactory
) ) );
65 xAccess
->kill( aURL
);
68 catch( const uno::Exception
& )
75 //----------------------------------------------
76 OUString
GetNewTempFileURL_Impl( const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
78 SAL_WARN_IF( !xFactory
.is(), "embeddedobj.ole", "No factory is provided!" );
82 uno::Reference
< beans::XPropertySet
> xTempFile(
83 io::TempFile::create(comphelper::getComponentContext(xFactory
)),
84 uno::UNO_QUERY_THROW
);
87 xTempFile
->setPropertyValue("RemoveFile", uno::makeAny( sal_False
) );
88 uno::Any aUrl
= xTempFile
->getPropertyValue("Uri");
91 catch ( const uno::Exception
& )
95 if ( aResult
.isEmpty() )
96 throw uno::RuntimeException(); // TODO: can not create tempfile
101 //-----------------------------------------------
102 OUString
GetNewFilledTempFile_Impl( const uno::Reference
< io::XInputStream
>& xInStream
,
103 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
104 throw ( io::IOException
,
105 uno::RuntimeException
)
107 OSL_ENSURE( xInStream
.is() && xFactory
.is(), "Wrong parameters are provided!\n" );
109 OUString aResult
= GetNewTempFileURL_Impl( xFactory
);
111 if ( !aResult
.isEmpty() )
114 uno::Reference
< ucb::XSimpleFileAccess3
> xTempAccess(
115 ucb::SimpleFileAccess::create( comphelper::getComponentContext(xFactory
) ) );
117 uno::Reference
< io::XOutputStream
> xTempOutStream
= xTempAccess
->openFileWrite( aResult
);
118 if ( xTempOutStream
.is() )
120 // copy stream contents to the file
121 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream
, xTempOutStream
);
122 xTempOutStream
->closeOutput();
123 xTempOutStream
= uno::Reference
< io::XOutputStream
>();
126 throw io::IOException(); // TODO:
128 catch( const packages::WrongPasswordException
& )
130 KillFile_Impl( aResult
, xFactory
);
131 throw io::IOException(); //TODO:
133 catch( const io::IOException
& )
135 KillFile_Impl( aResult
, xFactory
);
138 catch( const uno::RuntimeException
& )
140 KillFile_Impl( aResult
, xFactory
);
143 catch( const uno::Exception
& )
145 KillFile_Impl( aResult
, xFactory
);
146 aResult
= OUString();
153 OUString
GetNewFilledTempFile_Impl( const uno::Reference
< embed::XOptimizedStorage
>& xParentStorage
, const OUString
& aEntryName
, const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
154 throw( io::IOException
, uno::RuntimeException
)
160 uno::Reference
< beans::XPropertySet
> xTempFile(
161 io::TempFile::create(comphelper::getComponentContext(xFactory
)),
163 uno::Reference
< io::XStream
> xTempStream( xTempFile
, uno::UNO_QUERY_THROW
);
165 xParentStorage
->copyStreamElementData( aEntryName
, xTempStream
);
167 xTempFile
->setPropertyValue("RemoveFile", uno::makeAny( sal_False
) );
168 uno::Any aUrl
= xTempFile
->getPropertyValue("Uri");
171 catch( const uno::RuntimeException
& )
175 catch( const uno::Exception
& )
179 if ( aResult
.isEmpty() )
180 throw io::IOException();
185 //------------------------------------------------------
186 void SetStreamMediaType_Impl( const uno::Reference
< io::XStream
>& xStream
, const OUString
& aMediaType
)
188 uno::Reference
< beans::XPropertySet
> xPropSet( xStream
, uno::UNO_QUERY
);
189 if ( !xPropSet
.is() )
190 throw uno::RuntimeException(); // TODO: all the storage streams must support XPropertySet
192 xPropSet
->setPropertyValue("MediaType", uno::makeAny( aMediaType
) );
195 //------------------------------------------------------
196 void LetCommonStoragePassBeUsed_Impl( const uno::Reference
< io::XStream
>& xStream
)
198 uno::Reference
< beans::XPropertySet
> xPropSet( xStream
, uno::UNO_QUERY
);
199 if ( !xPropSet
.is() )
200 throw uno::RuntimeException(); // Only StorageStreams must be provided here, they must implement the interface
202 xPropSet
->setPropertyValue("UseCommonStoragePasswordEncryption",
203 uno::makeAny( (sal_Bool
)sal_True
) );
206 //------------------------------------------------------
207 void VerbExecutionController::StartControlExecution()
209 osl::MutexGuard
aGuard( m_aVerbExecutionMutex
);
211 // the class is used to detect STAMPIT object, that can never be active
212 if ( !m_bVerbExecutionInProgress
&& !m_bWasEverActive
)
214 m_bVerbExecutionInProgress
= sal_True
;
215 m_nVerbExecutionThreadIdentifier
= osl::Thread::getCurrentIdentifier();
216 m_bChangedOnVerbExecution
= sal_False
;
220 //------------------------------------------------------
221 sal_Bool
VerbExecutionController::EndControlExecution_WasModified()
223 osl::MutexGuard
aGuard( m_aVerbExecutionMutex
);
225 sal_Bool bResult
= sal_False
;
226 if ( m_bVerbExecutionInProgress
&& m_nVerbExecutionThreadIdentifier
== osl::Thread::getCurrentIdentifier() )
228 bResult
= m_bChangedOnVerbExecution
;
229 m_bVerbExecutionInProgress
= sal_False
;
235 //------------------------------------------------------
236 void VerbExecutionController::ModificationNotificationIsDone()
238 osl::MutexGuard
aGuard( m_aVerbExecutionMutex
);
240 if ( m_bVerbExecutionInProgress
&& osl::Thread::getCurrentIdentifier() == m_nVerbExecutionThreadIdentifier
)
241 m_bChangedOnVerbExecution
= sal_True
;
244 //-----------------------------------------------
245 void VerbExecutionController::LockNotification()
247 osl::MutexGuard
aGuard( m_aVerbExecutionMutex
);
248 if ( m_nNotificationLock
< SAL_MAX_INT32
)
249 m_nNotificationLock
++;
252 //-----------------------------------------------
253 void VerbExecutionController::UnlockNotification()
255 osl::MutexGuard
aGuard( m_aVerbExecutionMutex
);
256 if ( m_nNotificationLock
> 0 )
257 m_nNotificationLock
--;
260 //-----------------------------------------------
261 uno::Reference
< io::XStream
> OleEmbeddedObject::GetNewFilledTempStream_Impl( const uno::Reference
< io::XInputStream
>& xInStream
)
262 throw( io::IOException
)
264 SAL_WARN_IF( !xInStream
.is(), "embeddedobj.ole", "Wrong parameter is provided!" );
266 uno::Reference
< io::XStream
> xTempFile(
267 io::TempFile::create(comphelper::getComponentContext(m_xFactory
)),
268 uno::UNO_QUERY_THROW
);
270 uno::Reference
< io::XOutputStream
> xTempOutStream
= xTempFile
->getOutputStream();
271 if ( xTempOutStream
.is() )
273 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream
, xTempOutStream
);
274 xTempOutStream
->flush();
277 throw io::IOException(); // TODO:
282 //------------------------------------------------------
283 uno::Reference
< io::XStream
> OleEmbeddedObject::TryToGetAcceptableFormat_Impl( const uno::Reference
< io::XStream
>& xStream
)
284 throw ( uno::Exception
)
286 // TODO/LATER: Actually this should be done by a centralized component ( may be a graphical filter )
287 if ( !m_xFactory
.is() )
288 throw uno::RuntimeException();
290 uno::Reference
< io::XInputStream
> xInStream
= xStream
->getInputStream();
291 if ( !xInStream
.is() )
292 throw uno::RuntimeException();
294 uno::Reference
< io::XSeekable
> xSeek( xStream
, uno::UNO_QUERY_THROW
);
297 uno::Sequence
< sal_Int8
> aData( 8 );
298 sal_Int32 nRead
= xInStream
->readBytes( aData
, 8 );
301 if ( ( nRead
>= 2 && aData
[0] == 'B' && aData
[1] == 'M' )
302 || ( nRead
>= 4 && aData
[0] == 1 && aData
[1] == 0 && aData
[2] == 9 && aData
[3] == 0 ) )
304 // it should be a bitmap or a Metafile
309 sal_uInt32 nHeaderOffset
= 0;
310 if ( ( nRead
>= 8 && aData
[0] == -1 && aData
[1] == -1 && aData
[2] == -1 && aData
[3] == -1 )
311 && ( aData
[4] == 2 || aData
[4] == 3 || aData
[4] == 14 ) && aData
[5] == 0 && aData
[6] == 0 && aData
[7] == 0 )
316 // TargetDevice might be used in future, currently the cache has specified NULL
317 uno::Sequence
< sal_Int8
> aHeadData( 4 );
318 nRead
= xInStream
->readBytes( aHeadData
, 4 );
320 if ( nRead
== 4 && aHeadData
.getLength() == 4 )
321 nLen
= ( ( ( (sal_uInt32
)aHeadData
[3] * 0x100 + (sal_uInt32
)aHeadData
[2] ) * 0x100 ) + (sal_uInt32
)aHeadData
[1] ) * 0x100 + (sal_uInt32
)aHeadData
[0];
324 xInStream
->skipBytes( nLen
- 4 );
325 nHeaderOffset
+= nLen
- 4;
329 else if ( nRead
> 4 )
331 // check whether the first bytes represent the size
332 sal_uInt32 nSize
= 0;
333 for ( sal_Int32 nInd
= 3; nInd
>= 0; nInd
-- )
334 nSize
= ( nSize
<< 8 ) + (sal_uInt8
)aData
[nInd
];
336 if ( nSize
== xSeek
->getLength() - 4 )
342 // this is either a bitmap or a metafile clipboard format, retrieve the pure stream
343 uno::Reference
< io::XStream
> xResult(
344 io::TempFile::create(comphelper::getComponentContext(m_xFactory
)),
345 uno::UNO_QUERY_THROW
);
346 uno::Reference
< io::XSeekable
> xResultSeek( xResult
, uno::UNO_QUERY_THROW
);
347 uno::Reference
< io::XOutputStream
> xResultOut
= xResult
->getOutputStream();
348 uno::Reference
< io::XInputStream
> xResultIn
= xResult
->getInputStream();
349 if ( !xResultOut
.is() || !xResultIn
.is() )
350 throw uno::RuntimeException();
352 xSeek
->seek( nHeaderOffset
); // header size for these formats
353 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream
, xResultOut
);
354 xResultOut
->closeOutput();
355 xResultSeek
->seek( 0 );
361 return uno::Reference
< io::XStream
>();
364 //------------------------------------------------------
365 void OleEmbeddedObject::InsertVisualCache_Impl( const uno::Reference
< io::XStream
>& xTargetStream
,
366 const uno::Reference
< io::XStream
>& xCachedVisualRepresentation
)
367 throw ( uno::Exception
)
369 OSL_ENSURE( xTargetStream
.is() && xCachedVisualRepresentation
.is(), "Invalid argumants!\n" );
371 if ( !xTargetStream
.is() || !xCachedVisualRepresentation
.is() )
372 throw uno::RuntimeException();
374 uno::Sequence
< uno::Any
> aArgs( 2 );
375 aArgs
[0] <<= xTargetStream
;
376 aArgs
[1] <<= (sal_Bool
)sal_True
; // do not create copy
378 uno::Reference
< container::XNameContainer
> xNameContainer(
379 m_xFactory
->createInstanceWithArguments(
380 OUString( "com.sun.star.embed.OLESimpleStorage" ),
384 if ( !xNameContainer
.is() )
385 throw uno::RuntimeException();
387 uno::Reference
< io::XSeekable
> xCachedSeek( xCachedVisualRepresentation
, uno::UNO_QUERY_THROW
);
388 if ( xCachedSeek
.is() )
389 xCachedSeek
->seek( 0 );
391 uno::Reference
< io::XStream
> xTempFile(
392 io::TempFile::create(comphelper::getComponentContext(m_xFactory
)),
393 uno::UNO_QUERY_THROW
);
395 uno::Reference
< io::XSeekable
> xTempSeek( xTempFile
, uno::UNO_QUERY_THROW
);
396 uno::Reference
< io::XOutputStream
> xTempOutStream
= xTempFile
->getOutputStream();
397 if ( xTempOutStream
.is() )
399 // the OlePres stream must have additional header
400 // TODO/LATER: might need to be extended in future ( actually makes sence only for SO7 format )
401 uno::Reference
< io::XInputStream
> xInCacheStream
= xCachedVisualRepresentation
->getInputStream();
402 if ( !xInCacheStream
.is() )
403 throw uno::RuntimeException();
405 // write 0xFFFFFFFF at the beginning
406 uno::Sequence
< sal_Int8
> aData( 4 );
407 *( (sal_uInt32
*)aData
.getArray() ) = 0xFFFFFFFF;
409 xTempOutStream
->writeBytes( aData
);
411 // write clipboard format
412 uno::Sequence
< sal_Int8
> aSigData( 2 );
413 xInCacheStream
->readBytes( aSigData
, 2 );
414 if ( aSigData
.getLength() < 2 )
415 throw io::IOException();
417 if ( aSigData
[0] == 'B' && aSigData
[1] == 'M' )
420 aData
[0] = 0x02; aData
[1] = 0; aData
[2] = 0; aData
[3] = 0;
424 // treat it as a metafile
425 aData
[0] = 0x03; aData
[1] = 0; aData
[2] = 0; aData
[3] = 0;
427 xTempOutStream
->writeBytes( aData
);
429 // write job related information
430 aData
[0] = 0x04; aData
[1] = 0; aData
[2] = 0; aData
[3] = 0;
431 xTempOutStream
->writeBytes( aData
);
434 aData
[0] = 0x01; aData
[1] = 0; aData
[2] = 0; aData
[3] = 0;
435 xTempOutStream
->writeBytes( aData
);
438 *( (sal_uInt32
*)aData
.getArray() ) = 0xFFFFFFFF;
439 xTempOutStream
->writeBytes( aData
);
442 aData
[0] = 0x02; aData
[1] = 0; aData
[2] = 0; aData
[3] = 0;
443 xTempOutStream
->writeBytes( aData
);
446 *( (sal_uInt32
*)aData
.getArray() ) = 0x0;
447 xTempOutStream
->writeBytes( aData
);
450 awt::Size aSize
= getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
);
451 sal_Int32 nIndex
= 0;
454 for ( nIndex
= 0; nIndex
< 4; nIndex
++ )
456 aData
[nIndex
] = (sal_Int8
)( aSize
.Width
% 0x100 );
457 aSize
.Width
/= 0x100;
459 xTempOutStream
->writeBytes( aData
);
462 for ( nIndex
= 0; nIndex
< 4; nIndex
++ )
464 aData
[nIndex
] = (sal_Int8
)( aSize
.Height
% 0x100 );
465 aSize
.Height
/= 0x100;
467 xTempOutStream
->writeBytes( aData
);
469 // write garbage, it will be overwritten by the size
470 xTempOutStream
->writeBytes( aData
);
472 // write first bytes that was used to detect the type
473 xTempOutStream
->writeBytes( aSigData
);
475 // write the rest of the stream
476 ::comphelper::OStorageHelper::CopyInputToOutput( xInCacheStream
, xTempOutStream
);
478 // write the size of the stream
479 sal_Int64 nLength
= xTempSeek
->getLength() - 40;
480 if ( nLength
< 0 || nLength
>= 0xFFFFFFFF )
482 SAL_WARN( "embeddedobj.ole", "Length is not acceptable!" );
485 for ( sal_Int32 nInd
= 0; nInd
< 4; nInd
++ )
487 aData
[nInd
] = (sal_Int8
)( ( (sal_uInt64
) nLength
) % 0x100 );
490 xTempSeek
->seek( 36 );
491 xTempOutStream
->writeBytes( aData
);
493 xTempOutStream
->flush();
495 xTempSeek
->seek( 0 );
496 if ( xCachedSeek
.is() )
497 xCachedSeek
->seek( 0 );
500 throw io::IOException(); // TODO:
502 // insert the result file as replacement image
503 OUString aCacheName
= "\002OlePres000";
504 if ( xNameContainer
->hasByName( aCacheName
) )
505 xNameContainer
->replaceByName( aCacheName
, uno::makeAny( xTempFile
) );
507 xNameContainer
->insertByName( aCacheName
, uno::makeAny( xTempFile
) );
509 uno::Reference
< embed::XTransactedObject
> xTransacted( xNameContainer
, uno::UNO_QUERY
);
510 if ( !xTransacted
.is() )
511 throw uno::RuntimeException();
513 xTransacted
->commit();
516 //------------------------------------------------------
517 void OleEmbeddedObject::RemoveVisualCache_Impl( const uno::Reference
< io::XStream
>& xTargetStream
)
518 throw ( uno::Exception
)
520 OSL_ENSURE( xTargetStream
.is(), "Invalid argumant!\n" );
521 if ( !xTargetStream
.is() )
522 throw uno::RuntimeException();
524 uno::Sequence
< uno::Any
> aArgs( 2 );
525 aArgs
[0] <<= xTargetStream
;
526 aArgs
[1] <<= (sal_Bool
)sal_True
; // do not create copy
527 uno::Reference
< container::XNameContainer
> xNameContainer(
528 m_xFactory
->createInstanceWithArguments(
529 OUString( "com.sun.star.embed.OLESimpleStorage" ),
533 if ( !xNameContainer
.is() )
534 throw uno::RuntimeException();
536 for ( sal_uInt8 nInd
= 0; nInd
< 10; nInd
++ )
538 OUString aStreamName
= "\002OlePres00" + OUString::number( nInd
);
539 if ( xNameContainer
->hasByName( aStreamName
) )
540 xNameContainer
->removeByName( aStreamName
);
543 uno::Reference
< embed::XTransactedObject
> xTransacted( xNameContainer
, uno::UNO_QUERY
);
544 if ( !xTransacted
.is() )
545 throw uno::RuntimeException();
547 xTransacted
->commit();
550 //------------------------------------------------------
551 void OleEmbeddedObject::SetVisReplInStream( sal_Bool bExists
)
553 m_bVisReplInitialized
= sal_True
;
554 m_bVisReplInStream
= bExists
;
557 //------------------------------------------------------
558 sal_Bool
OleEmbeddedObject::HasVisReplInStream()
560 if ( !m_bVisReplInitialized
)
562 if ( m_xCachedVisualRepresentation
.is() )
563 SetVisReplInStream( sal_True
);
566 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::HasVisualReplInStream, analizing" );
568 uno::Reference
< io::XInputStream
> xStream
;
570 OSL_ENSURE( !m_pOleComponent
|| !m_aTempURL
.isEmpty(), "The temporary file must exist if there is a component!\n" );
571 if ( !m_aTempURL
.isEmpty() )
575 // open temporary file for reading
576 uno::Reference
< ucb::XSimpleFileAccess3
> xTempAccess(
577 ucb::SimpleFileAccess::create( comphelper::getComponentContext(m_xFactory
) ) );
579 xStream
= xTempAccess
->openFileRead( m_aTempURL
);
581 catch( const uno::Exception
& )
586 xStream
= m_xObjectStream
->getInputStream();
590 sal_Bool bExists
= sal_False
;
592 uno::Sequence
< uno::Any
> aArgs( 2 );
593 aArgs
[0] <<= xStream
;
594 aArgs
[1] <<= (sal_Bool
)sal_True
; // do not create copy
595 uno::Reference
< container::XNameContainer
> xNameContainer(
596 m_xFactory
->createInstanceWithArguments(
597 OUString( "com.sun.star.embed.OLESimpleStorage" ),
601 if ( xNameContainer
.is() )
603 for ( sal_uInt8 nInd
= 0; nInd
< 10 && !bExists
; nInd
++ )
605 OUString aStreamName
= "\002OlePres00" + OUString::number( nInd
);
608 bExists
= xNameContainer
->hasByName( aStreamName
);
610 catch( const uno::Exception
& )
615 SetVisReplInStream( bExists
);
620 return m_bVisReplInStream
;
623 //------------------------------------------------------
624 uno::Reference
< io::XStream
> OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation_Impl(
625 const uno::Reference
< io::XStream
>& xStream
,
626 sal_Bool bAllowToRepair50
)
629 uno::Reference
< io::XStream
> xResult
;
633 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::TryToRetrieveCachedVisualRepresentation, retrieving" );
635 uno::Reference
< container::XNameContainer
> xNameContainer
;
636 uno::Sequence
< uno::Any
> aArgs( 2 );
637 aArgs
[0] <<= xStream
;
638 aArgs
[1] <<= (sal_Bool
)sal_True
; // do not create copy
641 xNameContainer
= uno::Reference
< container::XNameContainer
>(
642 m_xFactory
->createInstanceWithArguments(
643 OUString( "com.sun.star.embed.OLESimpleStorage" ),
647 catch( const uno::Exception
& )
650 if ( xNameContainer
.is() )
652 for ( sal_uInt8 nInd
= 0; nInd
< 10; nInd
++ )
654 OUString aStreamName
= "\002OlePres00" + OUString::number( nInd
);
655 uno::Reference
< io::XStream
> xCachedCopyStream
;
658 if ( ( xNameContainer
->getByName( aStreamName
) >>= xCachedCopyStream
) && xCachedCopyStream
.is() )
660 xResult
= TryToGetAcceptableFormat_Impl( xCachedCopyStream
);
665 catch( const uno::Exception
& )
670 // to be compatible with the old versions Ole10Native is checked after OlePress000
671 aStreamName
= "\001Ole10Native";
674 if ( ( xNameContainer
->getByName( aStreamName
) >>= xCachedCopyStream
) && xCachedCopyStream
.is() )
676 xResult
= TryToGetAcceptableFormat_Impl( xCachedCopyStream
);
681 catch( const uno::Exception
& )
688 if ( bAllowToRepair50
&& !xResult
.is() )
690 OUString
aOrigContName( "Ole-Object" );
691 if ( xNameContainer
->hasByName( aOrigContName
) )
693 uno::Reference
< embed::XClassifiedObject
> xClassified( xNameContainer
, uno::UNO_QUERY_THROW
);
694 if ( MimeConfigurationHelper::ClassIDsEqual( xClassified
->getClassID(), MimeConfigurationHelper::GetSequenceClassID( SO3_OUT_CLASSID
) ) )
696 // this is an OLE object wrongly stored in 5.0 format
697 // this object must be repaired since SO7 has done it
699 uno::Reference
< io::XOutputStream
> xOutputStream
= xStream
->getOutputStream();
700 uno::Reference
< io::XTruncate
> xTruncate( xOutputStream
, uno::UNO_QUERY_THROW
);
702 uno::Reference
< io::XInputStream
> xOrigInputStream
;
703 if ( ( xNameContainer
->getByName( aOrigContName
) >>= xOrigInputStream
)
704 && xOrigInputStream
.is() )
706 // the provided input stream must be based on temporary medium and must be independent
707 // from the stream the storage is based on
708 uno::Reference
< io::XSeekable
> xOrigSeekable( xOrigInputStream
, uno::UNO_QUERY
);
709 if ( xOrigSeekable
.is() )
710 xOrigSeekable
->seek( 0 );
712 uno::Reference
< lang::XComponent
> xNameContDisp( xNameContainer
, uno::UNO_QUERY_THROW
);
713 xNameContDisp
->dispose(); // free the original stream
715 xTruncate
->truncate();
716 ::comphelper::OStorageHelper::CopyInputToOutput( xOrigInputStream
, xOutputStream
);
717 xOutputStream
->flush();
719 if ( xStream
== m_xObjectStream
)
721 if ( !m_aTempURL
.isEmpty() )
723 // this is the own stream, so the temporary URL must be cleaned if it exists
724 KillFile_Impl( m_aTempURL
, m_xFactory
);
725 m_aTempURL
= OUString();
729 // retry to create the component after recovering
734 CreateOleComponentAndLoad_Impl( NULL
);
735 m_aClassID
= m_pOleComponent
->GetCLSID(); // was not set during consruction
737 catch( const uno::Exception
& )
744 xResult
= TryToRetrieveCachedVisualRepresentation_Impl( xStream
, sal_False
);
750 catch( const uno::Exception
& )
758 //------------------------------------------------------
759 void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference
< embed::XStorage
>& xNewParentStorage
,
760 const uno::Reference
< io::XStream
>& xNewObjectStream
,
761 const OUString
& aNewName
)
763 if ( xNewParentStorage
== m_xParentStorage
&& aNewName
.equals( m_aEntryName
) )
765 SAL_WARN_IF( xNewObjectStream
!= m_xObjectStream
, "embeddedobj.ole", "The streams must be the same!" );
770 uno::Reference
< lang::XComponent
> xComponent( m_xObjectStream
, uno::UNO_QUERY
);
771 OSL_ENSURE( !m_xObjectStream
.is() || xComponent
.is(), "Wrong stream implementation!" );
772 if ( xComponent
.is() )
773 xComponent
->dispose();
775 catch ( const uno::Exception
& )
779 m_xObjectStream
= xNewObjectStream
;
780 m_xParentStorage
= xNewParentStorage
;
781 m_aEntryName
= aNewName
;
784 //------------------------------------------------------
785 void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference
< embed::XStorage
>& xNewParentStorage
,
786 const OUString
& aNewName
)
788 if ( xNewParentStorage
== m_xParentStorage
&& aNewName
.equals( m_aEntryName
) )
791 sal_Int32 nStreamMode
= m_bReadOnly
? embed::ElementModes::READ
: embed::ElementModes::READWRITE
;
793 uno::Reference
< io::XStream
> xNewOwnStream
= xNewParentStorage
->openStreamElement( aNewName
, nStreamMode
);
794 SAL_WARN_IF( !xNewOwnStream
.is(), "embeddedobj.ole", "The method can not return empty reference!" );
796 SwitchOwnPersistence( xNewParentStorage
, xNewOwnStream
, aNewName
);
800 //----------------------------------------------
801 sal_Bool
OleEmbeddedObject::SaveObject_Impl()
803 sal_Bool bResult
= sal_False
;
805 if ( m_xClientSite
.is() )
809 m_xClientSite
->saveObject();
812 catch( const uno::Exception
& )
820 //----------------------------------------------
821 sal_Bool
OleEmbeddedObject::OnShowWindow_Impl( sal_Bool bShow
)
823 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
825 sal_Bool bResult
= sal_False
;
827 SAL_WARN_IF( m_nObjectState
== -1, "embeddedobj.ole", "The object has no persistence!" );
828 SAL_WARN_IF( m_nObjectState
== embed::EmbedStates::LOADED
, "embeddedobj.ole", "The object get OnShowWindow in loaded state!" );
829 if ( m_nObjectState
== -1 || m_nObjectState
== embed::EmbedStates::LOADED
)
832 // the object is either activated or deactivated
833 sal_Int32 nOldState
= m_nObjectState
;
834 if ( bShow
&& m_nObjectState
== embed::EmbedStates::RUNNING
)
836 m_nObjectState
= embed::EmbedStates::ACTIVE
;
837 m_aVerbExecutionController
.ObjectIsActive();
840 StateChangeNotification_Impl( sal_False
, nOldState
, m_nObjectState
);
842 else if ( !bShow
&& m_nObjectState
== embed::EmbedStates::ACTIVE
)
844 m_nObjectState
= embed::EmbedStates::RUNNING
;
846 StateChangeNotification_Impl( sal_False
, nOldState
, m_nObjectState
);
849 if ( m_xClientSite
.is() )
853 m_xClientSite
->visibilityChanged( bShow
);
856 catch( const uno::Exception
& )
864 //------------------------------------------------------
865 void OleEmbeddedObject::OnIconChanged_Impl()
867 // TODO/LATER: currently this notification seems to be impossible
868 // MakeEventListenerNotification_Impl( OUString( "OnIconChanged" ) );
871 //------------------------------------------------------
872 void OleEmbeddedObject::OnViewChanged_Impl()
875 throw lang::DisposedException();
877 // For performance reasons the notification currently is ignored, STAMPIT object is the exception,
878 // it can never be active and never call SaveObject, so it is the only way to detect that it is changed
880 // ==== the STAMPIT related solution =============================
881 // the following variable is used to detect whether the object was modified during verb execution
882 m_aVerbExecutionController
.ModificationNotificationIsDone();
884 // The following things are controlled by VerbExecutionController:
885 // - if the verb execution is in progress and the view is changed the object will be stored
886 // after the execution, so there is no need to send the notification.
887 // - the STAMPIT object can never be active.
888 if ( m_aVerbExecutionController
.CanDoNotification()
889 && m_pOleComponent
&& m_nUpdateMode
== embed::EmbedUpdateModes::ALWAYS_UPDATE
)
891 OSL_ENSURE( MimeConfigurationHelper::ClassIDsEqual( m_aClassID
, MimeConfigurationHelper::GetSequenceClassID( 0x852ee1c9, 0x9058, 0x44ba, 0x8c,0x6c,0x0c,0x5f,0xc6,0x6b,0xdb,0x8d ) )
892 || MimeConfigurationHelper::ClassIDsEqual( m_aClassID
, MimeConfigurationHelper::GetSequenceClassID( 0xcf1b4491, 0xbea3, 0x4c9f, 0xa7,0x0f,0x22,0x1b,0x1e,0xca,0xef,0x3e ) ),
893 "Expected to be triggered for STAMPIT only! Please contact developers!\n" );
895 // The view is changed while the object is in running state, save the new object
896 m_xCachedVisualRepresentation
= uno::Reference
< io::XStream
>();
898 MakeEventListenerNotification_Impl( OUString( "OnVisAreaChanged" ) );
900 // ===============================================================
903 //------------------------------------------------------
904 void OleEmbeddedObject::OnClosed_Impl()
907 throw lang::DisposedException();
909 if ( m_nObjectState
!= embed::EmbedStates::LOADED
)
911 sal_Int32 nOldState
= m_nObjectState
;
912 m_nObjectState
= embed::EmbedStates::LOADED
;
913 StateChangeNotification_Impl( sal_False
, nOldState
, m_nObjectState
);
917 //------------------------------------------------------
918 OUString
OleEmbeddedObject::CreateTempURLEmpty_Impl()
920 SAL_WARN_IF( !m_aTempURL
.isEmpty(), "embeddedobj.ole", "The object has already the temporary file!" );
921 m_aTempURL
= GetNewTempFileURL_Impl( m_xFactory
);
926 //------------------------------------------------------
927 OUString
OleEmbeddedObject::GetTempURL_Impl()
929 if ( m_aTempURL
.isEmpty() )
931 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::GetTempURL_Impl, tempfile creation" );
933 // if there is no temporary file, it will be created from the own entry
934 uno::Reference
< embed::XOptimizedStorage
> xOptParStorage( m_xParentStorage
, uno::UNO_QUERY
);
935 if ( xOptParStorage
.is() )
937 m_aTempURL
= GetNewFilledTempFile_Impl( xOptParStorage
, m_aEntryName
, m_xFactory
);
939 else if ( m_xObjectStream
.is() )
941 // load object from the stream
942 uno::Reference
< io::XInputStream
> xInStream
= m_xObjectStream
->getInputStream();
943 if ( !xInStream
.is() )
944 throw io::IOException(); // TODO: access denied
946 m_aTempURL
= GetNewFilledTempFile_Impl( xInStream
, m_xFactory
);
953 //------------------------------------------------------
954 void OleEmbeddedObject::CreateOleComponent_Impl( OleComponent
* pOleComponent
)
956 if ( !m_pOleComponent
)
958 m_pOleComponent
= pOleComponent
? pOleComponent
: new OleComponent( m_xFactory
, this );
959 m_pOleComponent
->acquire(); // TODO: needs holder?
961 if ( !m_xClosePreventer
.is() )
962 m_xClosePreventer
= uno::Reference
< util::XCloseListener
>(
963 static_cast< ::cppu::OWeakObject
* >( new OClosePreventer
),
966 m_pOleComponent
->addCloseListener( m_xClosePreventer
);
970 //------------------------------------------------------
971 void OleEmbeddedObject::CreateOleComponentAndLoad_Impl( OleComponent
* pOleComponent
)
973 if ( !m_pOleComponent
)
975 if ( !m_xObjectStream
.is() )
976 throw uno::RuntimeException();
978 CreateOleComponent_Impl( pOleComponent
);
980 // after the loading the object can appear as a link
981 // will be detected later by olecomponent
984 if ( m_aTempURL
.isEmpty() )
985 throw uno::RuntimeException(); // TODO
987 m_pOleComponent
->LoadEmbeddedObject( m_aTempURL
);
991 //------------------------------------------------------
992 void OleEmbeddedObject::CreateOleComponentFromClipboard_Impl( OleComponent
* pOleComponent
)
994 if ( !m_pOleComponent
)
996 if ( !m_xObjectStream
.is() )
997 throw uno::RuntimeException();
999 CreateOleComponent_Impl( pOleComponent
);
1001 // after the loading the object can appear as a link
1002 // will be detected later by olecomponent
1003 m_pOleComponent
->CreateObjectFromClipboard();
1007 //------------------------------------------------------
1008 uno::Reference
< io::XOutputStream
> OleEmbeddedObject::GetStreamForSaving()
1010 if ( !m_xObjectStream
.is() )
1011 throw uno::RuntimeException(); //TODO:
1013 uno::Reference
< io::XOutputStream
> xOutStream
= m_xObjectStream
->getOutputStream();
1014 if ( !xOutStream
.is() )
1015 throw io::IOException(); //TODO: access denied
1017 uno::Reference
< io::XTruncate
> xTruncate( xOutStream
, uno::UNO_QUERY
);
1018 if ( !xTruncate
.is() )
1019 throw uno::RuntimeException(); //TODO:
1021 xTruncate
->truncate();
1026 //----------------------------------------------
1027 void OleEmbeddedObject::StoreObjectToStream( uno::Reference
< io::XOutputStream
> xOutStream
)
1028 throw ( uno::Exception
)
1030 // this method should be used only on windows
1031 if ( m_pOleComponent
)
1032 m_pOleComponent
->StoreOwnTmpIfNecessary();
1034 // now all the changes should be in temporary location
1035 if ( m_aTempURL
.isEmpty() )
1036 throw uno::RuntimeException();
1038 // open temporary file for reading
1039 uno::Reference
< ucb::XSimpleFileAccess3
> xTempAccess(
1040 ucb::SimpleFileAccess::create( comphelper::getComponentContext(m_xFactory
) ) );
1042 uno::Reference
< io::XInputStream
> xTempInStream
= xTempAccess
->openFileRead( m_aTempURL
);
1043 SAL_WARN_IF( !xTempInStream
.is(), "embeddedobj.ole", "The object's temporary file can not be reopened for reading!" );
1045 // TODO: use bStoreVisReplace
1047 if ( xTempInStream
.is() )
1049 // write all the contents to XOutStream
1050 uno::Reference
< io::XTruncate
> xTrunc( xOutStream
, uno::UNO_QUERY
);
1052 throw uno::RuntimeException(); //TODO:
1056 ::comphelper::OStorageHelper::CopyInputToOutput( xTempInStream
, xOutStream
);
1059 throw io::IOException(); // TODO:
1061 // TODO: should the view replacement be in the stream ???
1062 // probably it must be specified on storing
1065 //------------------------------------------------------
1066 void OleEmbeddedObject::StoreToLocation_Impl(
1067 const uno::Reference
< embed::XStorage
>& xStorage
,
1068 const OUString
& sEntName
,
1069 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
,
1071 throw ( uno::Exception
)
1073 // TODO: use lObjArgs
1074 // TODO: exchange StoreVisualReplacement by SO file format version?
1076 if ( m_nObjectState
== -1 )
1078 // the object is still not loaded
1079 throw embed::WrongStateException( OUString( "Can't store object without persistence!\n" ),
1080 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1083 if ( m_bWaitSaveCompleted
)
1084 throw embed::WrongStateException(
1085 OUString( "The object waits for saveCompleted() call!\n" ),
1086 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1088 OSL_ENSURE( m_xParentStorage
.is() && m_xObjectStream
.is(), "The object has no valid persistence!\n" );
1090 sal_Bool bVisReplIsStored
= sal_False
;
1092 sal_Bool bTryOptimization
= sal_False
;
1093 sal_Bool bStoreVis
= m_bStoreVisRepl
;
1094 uno::Reference
< io::XStream
> xCachedVisualRepresentation
;
1095 for ( sal_Int32 nInd
= 0; nInd
< lObjArgs
.getLength(); nInd
++ )
1097 if ( lObjArgs
[nInd
].Name
== "StoreVisualReplacement" )
1098 lObjArgs
[nInd
].Value
>>= bStoreVis
;
1099 else if ( lObjArgs
[nInd
].Name
== "VisualReplacement" )
1100 lObjArgs
[nInd
].Value
>>= xCachedVisualRepresentation
;
1101 else if ( lObjArgs
[nInd
].Name
== "CanTryOptimization" )
1102 lObjArgs
[nInd
].Value
>>= bTryOptimization
;
1105 // ignore visual representation provided from outside if it should not be stored
1107 xCachedVisualRepresentation
= uno::Reference
< io::XStream
>();
1109 if ( bStoreVis
&& !HasVisReplInStream() && !xCachedVisualRepresentation
.is() )
1110 throw io::IOException(); // TODO: there is no cached visual representation and nothing is provided from outside
1112 // if the representation is provided from outside it should be copied to a local stream
1113 sal_Bool bNeedLocalCache
= xCachedVisualRepresentation
.is();
1115 uno::Reference
< io::XStream
> xTargetStream
;
1117 sal_Bool bStoreLoaded
= sal_False
;
1118 if ( m_nObjectState
== embed::EmbedStates::LOADED
1120 // if the object was NOT modified after storing it can be just copied
1121 // as if it was in loaded state
1122 || ( m_pOleComponent
&& !m_pOleComponent
->IsDirty() )
1126 sal_Bool bOptimizedCopyingDone
= sal_False
;
1128 if ( bTryOptimization
&& bStoreVis
== HasVisReplInStream() )
1132 uno::Reference
< embed::XOptimizedStorage
> xSourceOptStor( m_xParentStorage
, uno::UNO_QUERY_THROW
);
1133 uno::Reference
< embed::XOptimizedStorage
> xTargetOptStor( xStorage
, uno::UNO_QUERY_THROW
);
1134 xSourceOptStor
->copyElementDirectlyTo( m_aEntryName
, xTargetOptStor
, sEntName
);
1135 bOptimizedCopyingDone
= sal_True
;
1137 catch( const uno::Exception
& )
1142 if ( !bOptimizedCopyingDone
)
1144 // if optimized copying fails a normal one should be tried
1145 m_xParentStorage
->copyElementTo( m_aEntryName
, xStorage
, sEntName
);
1148 // the locally retrieved representation is always preferable
1149 // since the object is in loaded state the representation is unchanged
1150 if ( m_xCachedVisualRepresentation
.is() )
1152 xCachedVisualRepresentation
= m_xCachedVisualRepresentation
;
1153 bNeedLocalCache
= sal_False
;
1156 bVisReplIsStored
= HasVisReplInStream();
1157 bStoreLoaded
= sal_True
;
1160 else if ( m_pOleComponent
)
1163 xStorage
->openStreamElement( sEntName
, embed::ElementModes::READWRITE
);
1164 if ( !xTargetStream
.is() )
1165 throw io::IOException(); //TODO: access denied
1167 SetStreamMediaType_Impl( xTargetStream
, OUString( "application/vnd.sun.star.oleobject" ));
1168 uno::Reference
< io::XOutputStream
> xOutStream
= xTargetStream
->getOutputStream();
1169 if ( !xOutStream
.is() )
1170 throw io::IOException(); //TODO: access denied
1172 StoreObjectToStream( xOutStream
);
1173 bVisReplIsStored
= sal_True
;
1177 // no need to do it on StoreTo since in this case the replacement is in the stream
1178 // and there is no need to cache it even if it is thrown away because the object
1179 // is not changed by StoreTo action
1181 uno::Reference
< io::XStream
> xTmpCVRepresentation
=
1182 TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream
);
1184 // the locally retrieved representation is always preferable
1185 if ( xTmpCVRepresentation
.is() )
1187 xCachedVisualRepresentation
= xTmpCVRepresentation
;
1188 bNeedLocalCache
= sal_False
;
1195 throw io::IOException(); // TODO
1198 if ( !xTargetStream
.is() )
1201 xStorage
->openStreamElement( sEntName
, embed::ElementModes::READWRITE
);
1202 if ( !xTargetStream
.is() )
1203 throw io::IOException(); //TODO: access denied
1206 LetCommonStoragePassBeUsed_Impl( xTargetStream
);
1208 if ( bStoreVis
!= bVisReplIsStored
)
1212 if ( !xCachedVisualRepresentation
.is() )
1213 xCachedVisualRepresentation
= TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream
);
1215 SAL_WARN_IF( !xCachedVisualRepresentation
.is(), "embeddedobj.ole", "No representation is available!" );
1217 // the following copying will be done in case it is SaveAs anyway
1218 // if it is not SaveAs the seekable access is not required currently
1219 // TODO/LATER: may be required in future
1222 uno::Reference
< io::XSeekable
> xCachedSeek( xCachedVisualRepresentation
, uno::UNO_QUERY
);
1223 if ( !xCachedSeek
.is() )
1225 xCachedVisualRepresentation
1226 = GetNewFilledTempStream_Impl( xCachedVisualRepresentation
->getInputStream() );
1227 bNeedLocalCache
= sal_False
;
1231 InsertVisualCache_Impl( xTargetStream
, xCachedVisualRepresentation
);
1235 // the removed representation could be cached by this method
1236 if ( !xCachedVisualRepresentation
.is() )
1237 xCachedVisualRepresentation
= TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream
);
1239 RemoveVisualCache_Impl( xTargetStream
);
1245 m_bWaitSaveCompleted
= sal_True
;
1246 m_xNewObjectStream
= xTargetStream
;
1247 m_xNewParentStorage
= xStorage
;
1248 m_aNewEntryName
= sEntName
;
1249 m_bNewVisReplInStream
= bStoreVis
;
1250 m_bStoreLoaded
= bStoreLoaded
;
1252 if ( xCachedVisualRepresentation
.is() )
1254 if ( bNeedLocalCache
)
1255 m_xNewCachedVisRepl
= GetNewFilledTempStream_Impl( xCachedVisualRepresentation
->getInputStream() );
1257 m_xNewCachedVisRepl
= xCachedVisualRepresentation
;
1260 // TODO: register listeners for storages above, in case they are disposed
1261 // an exception will be thrown on saveCompleted( true )
1265 uno::Reference
< lang::XComponent
> xComp( xTargetStream
, uno::UNO_QUERY
);
1270 } catch( const uno::Exception
& )
1277 //------------------------------------------------------
1278 void SAL_CALL
OleEmbeddedObject::setPersistentEntry(
1279 const uno::Reference
< embed::XStorage
>& xStorage
,
1280 const OUString
& sEntName
,
1281 sal_Int32 nEntryConnectionMode
,
1282 const uno::Sequence
< beans::PropertyValue
>& lArguments
,
1283 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
1284 throw ( lang::IllegalArgumentException
,
1285 embed::WrongStateException
,
1288 uno::RuntimeException
)
1290 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::setPersistentEntry" );
1292 // begin wrapping related part ====================
1293 uno::Reference
< embed::XEmbedPersist
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
1294 if ( xWrappedObject
.is() )
1296 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1297 xWrappedObject
->setPersistentEntry( xStorage
, sEntName
, nEntryConnectionMode
, lArguments
, lObjArgs
);
1300 // end wrapping related part ====================
1302 // TODO: use lObjArgs
1304 // the type of the object must be already set
1305 // a kind of typedetection should be done in the factory;
1306 // the only exception is object initialized from a stream,
1307 // the class ID will be detected from the stream
1309 ::osl::MutexGuard
aGuard( m_aMutex
);
1311 throw lang::DisposedException(); // TODO
1313 if ( !xStorage
.is() )
1314 throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
1315 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
1318 if ( sEntName
.isEmpty() )
1319 throw lang::IllegalArgumentException( OUString( "Empty element name is provided!\n" ),
1320 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
1323 // May be LOADED should be forbidden here ???
1324 if ( ( m_nObjectState
!= -1 || nEntryConnectionMode
== embed::EntryInitModes::NO_INIT
)
1325 && ( m_nObjectState
== -1 || nEntryConnectionMode
!= embed::EntryInitModes::NO_INIT
) )
1327 // if the object is not loaded
1328 // it can not get persistent representation without initialization
1330 // if the object is loaded
1331 // it can switch persistent representation only without initialization
1333 throw embed::WrongStateException(
1334 OUString( "Can't change persistent representation of activated object!\n" ),
1335 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1338 if ( m_bWaitSaveCompleted
)
1340 if ( nEntryConnectionMode
== embed::EntryInitModes::NO_INIT
)
1341 saveCompleted( ( m_xParentStorage
!= xStorage
|| !m_aEntryName
.equals( sEntName
) ) );
1343 throw embed::WrongStateException(
1344 OUString( "The object waits for saveCompleted() call!\n" ),
1345 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1348 uno::Reference
< container::XNameAccess
> xNameAccess( xStorage
, uno::UNO_QUERY
);
1349 if ( !xNameAccess
.is() )
1350 throw uno::RuntimeException(); //TODO
1352 // detect entry existence
1353 sal_Bool bElExists
= xNameAccess
->hasByName( sEntName
);
1355 m_bReadOnly
= sal_False
;
1356 for ( sal_Int32 nInd
= 0; nInd
< lArguments
.getLength(); nInd
++ )
1357 if ( lArguments
[nInd
].Name
== "ReadOnly" )
1358 lArguments
[nInd
].Value
>>= m_bReadOnly
;
1361 sal_Int32 nStorageMode
= m_bReadOnly
? embed::ElementModes::READ
: embed::ElementModes::READWRITE
;
1364 SwitchOwnPersistence( xStorage
, sEntName
);
1366 for ( sal_Int32 nInd
= 0; nInd
< lObjArgs
.getLength(); nInd
++ )
1367 if ( lObjArgs
[nInd
].Name
== "StoreVisualReplacement" )
1368 lObjArgs
[nInd
].Value
>>= m_bStoreVisRepl
;
1371 if ( nEntryConnectionMode
== embed::EntryInitModes::DEFAULT_INIT
)
1373 if ( m_bFromClipboard
)
1375 // the object should be initialized from clipboard
1376 // inpossibility to initialize the object means error here
1377 CreateOleComponentFromClipboard_Impl( NULL
);
1378 m_aClassID
= m_pOleComponent
->GetCLSID(); // was not set during consruction
1379 m_pOleComponent
->RunObject();
1380 m_nObjectState
= embed::EmbedStates::RUNNING
;
1382 else if ( bElExists
)
1384 // load object from the stream
1385 // after the loading the object can appear as a link
1386 // will be detected by olecomponent
1389 CreateOleComponentAndLoad_Impl( NULL
);
1390 m_aClassID
= m_pOleComponent
->GetCLSID(); // was not set during consruction
1392 catch( const uno::Exception
& )
1394 // TODO/LATER: detect classID of the object if possible
1395 // means that the object inprocess server could not be successfully instantiated
1396 GetRidOfComponent();
1399 m_nObjectState
= embed::EmbedStates::LOADED
;
1403 // create a new object
1404 CreateOleComponent_Impl();
1405 m_pOleComponent
->CreateNewEmbeddedObject( m_aClassID
);
1406 m_pOleComponent
->RunObject();
1407 m_nObjectState
= embed::EmbedStates::RUNNING
;
1412 if ( ( nStorageMode
& embed::ElementModes::READWRITE
) != embed::ElementModes::READWRITE
)
1413 throw io::IOException();
1415 if ( nEntryConnectionMode
== embed::EntryInitModes::NO_INIT
)
1417 // the document just already changed its stream to store to;
1418 // the links to OLE documents switch their persistence in the same way
1419 // as normal embedded objects
1421 else if ( nEntryConnectionMode
== embed::EntryInitModes::TRUNCATE_INIT
)
1423 // create a new object, that will be stored in specified stream
1424 CreateOleComponent_Impl();
1426 m_pOleComponent
->CreateNewEmbeddedObject( m_aClassID
);
1427 m_pOleComponent
->RunObject();
1428 m_nObjectState
= embed::EmbedStates::RUNNING
;
1430 else if ( nEntryConnectionMode
== embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT
)
1432 // use URL ( may be content or stream later ) from MediaDescriptor to initialize object
1434 for ( sal_Int32 nInd
= 0; nInd
< lArguments
.getLength(); nInd
++ )
1435 if ( lArguments
[nInd
].Name
== "URL" )
1436 lArguments
[nInd
].Value
>>= aURL
;
1438 if ( aURL
.isEmpty() )
1439 throw lang::IllegalArgumentException(
1440 OUString( "Empty URL is provided in the media descriptor!\n" ),
1441 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
1444 CreateOleComponent_Impl();
1446 // TODO: the m_bIsLink value must be set already
1448 m_pOleComponent
->CreateObjectFromFile( aURL
);
1450 m_pOleComponent
->CreateLinkFromFile( aURL
);
1452 m_pOleComponent
->RunObject();
1453 m_aClassID
= m_pOleComponent
->GetCLSID(); // was not set during consruction
1455 m_nObjectState
= embed::EmbedStates::RUNNING
;
1457 //else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT )
1462 throw lang::IllegalArgumentException( OUString( "Wrong connection mode is provided!\n" ),
1463 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
1467 // On unix the ole object can not do anything except storing itself somewere
1468 if ( nEntryConnectionMode
== embed::EntryInitModes::DEFAULT_INIT
&& bElExists
)
1470 // TODO/LATER: detect classID of the object
1471 // can be a real problem for the links
1473 m_nObjectState
= embed::EmbedStates::LOADED
;
1475 else if ( nEntryConnectionMode
== embed::EntryInitModes::NO_INIT
)
1477 // do nothing, the object has already switched it's persistence
1480 throw lang::IllegalArgumentException( OUString( "Wrong connection mode is provided!\n" ),
1481 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
1487 //------------------------------------------------------
1488 void SAL_CALL
OleEmbeddedObject::storeToEntry( const uno::Reference
< embed::XStorage
>& xStorage
,
1489 const OUString
& sEntName
,
1490 const uno::Sequence
< beans::PropertyValue
>& lArguments
,
1491 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
1492 throw ( lang::IllegalArgumentException
,
1493 embed::WrongStateException
,
1496 uno::RuntimeException
)
1498 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::storeToEntry" );
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
);
1508 // end wrapping related part ====================
1510 ::osl::MutexGuard
aGuard( m_aMutex
);
1512 throw lang::DisposedException(); // TODO
1514 VerbExecutionControllerGuard
aVerbGuard( m_aVerbExecutionController
);
1516 StoreToLocation_Impl( xStorage
, sEntName
, lObjArgs
, sal_False
);
1518 // TODO: should the listener notification be done?
1521 //------------------------------------------------------
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
,
1530 uno::RuntimeException
)
1532 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::storeAsEntry" );
1534 // begin wrapping related part ====================
1535 uno::Reference
< embed::XEmbedPersist
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
1536 if ( xWrappedObject
.is() )
1538 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1539 xWrappedObject
->storeAsEntry( xStorage
, sEntName
, lArguments
, lObjArgs
);
1542 // end wrapping related part ====================
1544 ::osl::MutexGuard
aGuard( m_aMutex
);
1546 throw lang::DisposedException(); // TODO
1548 VerbExecutionControllerGuard
aVerbGuard( m_aVerbExecutionController
);
1550 StoreToLocation_Impl( xStorage
, sEntName
, lObjArgs
, sal_True
);
1552 // TODO: should the listener notification be done here or in saveCompleted?
1555 //------------------------------------------------------
1556 void SAL_CALL
OleEmbeddedObject::saveCompleted( sal_Bool bUseNew
)
1557 throw ( embed::WrongStateException
,
1559 uno::RuntimeException
)
1561 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::saveCompleted" );
1563 // begin wrapping related part ====================
1564 uno::Reference
< embed::XEmbedPersist
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
1565 if ( xWrappedObject
.is() )
1567 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1568 xWrappedObject
->saveCompleted( bUseNew
);
1571 // end wrapping related part ====================
1573 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
1575 throw lang::DisposedException(); // TODO
1577 if ( m_nObjectState
== -1 )
1579 // the object is still not loaded
1580 throw embed::WrongStateException( OUString( "Can't store object without persistence!\n" ),
1581 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1584 // it is allowed to call saveCompleted( false ) for nonstored objects
1585 if ( !m_bWaitSaveCompleted
&& !bUseNew
)
1588 SAL_WARN_IF( !m_bWaitSaveCompleted
, "embeddedobj.ole", "Unexpected saveCompleted() call!\n" );
1589 if ( !m_bWaitSaveCompleted
)
1590 throw io::IOException(); // TODO: illegal call
1592 OSL_ENSURE( m_xNewObjectStream
.is() && m_xNewParentStorage
.is() , "Internal object information is broken!\n" );
1593 if ( !m_xNewObjectStream
.is() || !m_xNewParentStorage
.is() )
1594 throw uno::RuntimeException(); // TODO: broken internal information
1598 SwitchOwnPersistence( m_xNewParentStorage
, m_xNewObjectStream
, m_aNewEntryName
);
1599 m_bStoreVisRepl
= m_bNewVisReplInStream
;
1600 SetVisReplInStream( m_bNewVisReplInStream
);
1601 m_xCachedVisualRepresentation
= m_xNewCachedVisRepl
;
1605 // close remembered stream
1607 uno::Reference
< lang::XComponent
> xComponent( m_xNewObjectStream
, uno::UNO_QUERY
);
1608 SAL_WARN_IF( !xComponent
.is(), "embeddedobj.ole", "Wrong storage implementation!" );
1609 if ( xComponent
.is() )
1610 xComponent
->dispose();
1612 catch ( const uno::Exception
& )
1617 sal_Bool bStoreLoaded
= m_bStoreLoaded
;
1619 m_xNewObjectStream
= uno::Reference
< io::XStream
>();
1620 m_xNewParentStorage
= uno::Reference
< embed::XStorage
>();
1621 m_aNewEntryName
= OUString();
1622 m_bWaitSaveCompleted
= sal_False
;
1623 m_bNewVisReplInStream
= sal_False
;
1624 m_xNewCachedVisRepl
= uno::Reference
< io::XStream
>();
1625 m_bStoreLoaded
= sal_False
;
1627 if ( bUseNew
&& m_pOleComponent
&& m_nUpdateMode
== embed::EmbedUpdateModes::ALWAYS_UPDATE
&& !bStoreLoaded
1628 && m_nObjectState
!= embed::EmbedStates::LOADED
)
1630 // the object replacement image should be updated, so the cached size as well
1631 m_bHasCachedSize
= sal_False
;
1634 // the call will cache the size in case of success
1635 // probably it might need to be done earlier, while the object is in active state
1636 getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
);
1638 catch( const uno::Exception
& )
1645 MakeEventListenerNotification_Impl( OUString( "OnSaveAsDone" ));
1647 // the object can be changed only on windows
1648 // the notification should be done only if the object is not in loaded state
1649 if ( m_pOleComponent
&& m_nUpdateMode
== embed::EmbedUpdateModes::ALWAYS_UPDATE
&& !bStoreLoaded
)
1651 MakeEventListenerNotification_Impl( OUString( "OnVisAreaChanged" ));
1656 //------------------------------------------------------
1657 sal_Bool SAL_CALL
OleEmbeddedObject::hasEntry()
1658 throw ( embed::WrongStateException
,
1659 uno::RuntimeException
)
1661 // begin wrapping related part ====================
1662 uno::Reference
< embed::XEmbedPersist
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
1663 if ( xWrappedObject
.is() )
1665 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1666 return xWrappedObject
->hasEntry();
1668 // end wrapping related part ====================
1670 ::osl::MutexGuard
aGuard( m_aMutex
);
1672 throw lang::DisposedException(); // TODO
1674 if ( m_bWaitSaveCompleted
)
1675 throw embed::WrongStateException(
1676 OUString( "The object waits for saveCompleted() call!\n" ),
1677 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1679 if ( m_xObjectStream
.is() )
1685 //------------------------------------------------------
1686 OUString SAL_CALL
OleEmbeddedObject::getEntryName()
1687 throw ( embed::WrongStateException
,
1688 uno::RuntimeException
)
1690 // begin wrapping related part ====================
1691 uno::Reference
< embed::XEmbedPersist
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
1692 if ( xWrappedObject
.is() )
1694 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1695 return xWrappedObject
->getEntryName();
1697 // end wrapping related part ====================
1699 ::osl::MutexGuard
aGuard( m_aMutex
);
1701 throw lang::DisposedException(); // TODO
1703 if ( m_nObjectState
== -1 )
1705 // the object is still not loaded
1706 throw embed::WrongStateException( OUString( "The object persistence is not initialized!\n" ),
1707 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1710 if ( m_bWaitSaveCompleted
)
1711 throw embed::WrongStateException(
1712 OUString( "The object waits for saveCompleted() call!\n" ),
1713 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1715 return m_aEntryName
;
1719 //------------------------------------------------------
1720 void SAL_CALL
OleEmbeddedObject::storeOwn()
1721 throw ( embed::WrongStateException
,
1724 uno::RuntimeException
)
1726 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::storeOwn" );
1728 // begin wrapping related part ====================
1729 uno::Reference
< embed::XEmbedPersist
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
1730 if ( xWrappedObject
.is() )
1732 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1733 xWrappedObject
->storeOwn();
1736 // end wrapping related part ====================
1738 // during switching from Activated to Running and from Running to Loaded states the object will
1739 // ask container to store the object, the container has to make decision
1742 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
1744 throw lang::DisposedException(); // TODO
1746 VerbExecutionControllerGuard
aVerbGuard( m_aVerbExecutionController
);
1748 if ( m_nObjectState
== -1 )
1750 // the object is still not loaded
1751 throw embed::WrongStateException( OUString( "Can't store object without persistence!\n" ),
1752 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1755 if ( m_bWaitSaveCompleted
)
1756 throw embed::WrongStateException(
1757 OUString( "The object waits for saveCompleted() call!\n" ),
1758 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1761 throw io::IOException(); // TODO: access denied
1763 LetCommonStoragePassBeUsed_Impl( m_xObjectStream
);
1765 sal_Bool bStoreLoaded
= sal_True
;
1768 if ( m_nObjectState
!= embed::EmbedStates::LOADED
&& m_pOleComponent
&& m_pOleComponent
->IsDirty() )
1770 bStoreLoaded
= sal_False
;
1772 OSL_ENSURE( m_xParentStorage
.is() && m_xObjectStream
.is(), "The object has no valid persistence!\n" );
1774 if ( !m_xObjectStream
.is() )
1775 throw io::IOException(); //TODO: access denied
1777 SetStreamMediaType_Impl( m_xObjectStream
, OUString( "application/vnd.sun.star.oleobject" ));
1778 uno::Reference
< io::XOutputStream
> xOutStream
= m_xObjectStream
->getOutputStream();
1779 if ( !xOutStream
.is() )
1780 throw io::IOException(); //TODO: access denied
1782 // TODO: does this work for links too?
1783 StoreObjectToStream( GetStreamForSaving() );
1785 // the replacement is changed probably, and it must be in the object stream
1786 if ( !m_pOleComponent
->IsWorkaroundActive() )
1787 m_xCachedVisualRepresentation
= uno::Reference
< io::XStream
>();
1788 SetVisReplInStream( sal_True
);
1792 if ( m_bStoreVisRepl
!= HasVisReplInStream() )
1794 if ( m_bStoreVisRepl
)
1796 // the m_xCachedVisualRepresentation must be set or it should be already stored
1797 if ( m_xCachedVisualRepresentation
.is() )
1798 InsertVisualCache_Impl( m_xObjectStream
, m_xCachedVisualRepresentation
);
1801 m_xCachedVisualRepresentation
= TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream
);
1802 SAL_WARN_IF( !m_xCachedVisualRepresentation
.is(), "embeddedobj.ole", "No representation is available!" );
1807 if ( !m_xCachedVisualRepresentation
.is() )
1808 m_xCachedVisualRepresentation
= TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream
);
1809 RemoveVisualCache_Impl( m_xObjectStream
);
1812 SetVisReplInStream( m_bStoreVisRepl
);
1815 if ( m_pOleComponent
&& m_nUpdateMode
== embed::EmbedUpdateModes::ALWAYS_UPDATE
&& !bStoreLoaded
)
1817 // the object replacement image should be updated, so the cached size as well
1818 m_bHasCachedSize
= sal_False
;
1821 // the call will cache the size in case of success
1822 // probably it might need to be done earlier, while the object is in active state
1823 getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
);
1825 catch( const uno::Exception
& )
1831 MakeEventListenerNotification_Impl( OUString( "OnSaveDone" ));
1833 // the object can be changed only on Windows
1834 // the notification should be done only if the object is not in loaded state
1835 if ( m_pOleComponent
&& m_nUpdateMode
== embed::EmbedUpdateModes::ALWAYS_UPDATE
&& !bStoreLoaded
)
1836 MakeEventListenerNotification_Impl( OUString( "OnVisAreaChanged" ));
1839 //------------------------------------------------------
1840 sal_Bool SAL_CALL
OleEmbeddedObject::isReadonly()
1841 throw ( embed::WrongStateException
,
1842 uno::RuntimeException
)
1844 // begin wrapping related part ====================
1845 uno::Reference
< embed::XEmbedPersist
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
1846 if ( xWrappedObject
.is() )
1848 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1849 return xWrappedObject
->isReadonly();
1851 // end wrapping related part ====================
1853 ::osl::MutexGuard
aGuard( m_aMutex
);
1855 throw lang::DisposedException(); // TODO
1857 if ( m_nObjectState
== -1 )
1859 // the object is still not loaded
1860 throw embed::WrongStateException( OUString( "The object persistence is not initialized!\n" ),
1861 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1864 if ( m_bWaitSaveCompleted
)
1865 throw embed::WrongStateException(
1866 OUString( "The object waits for saveCompleted() call!\n" ),
1867 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1872 //------------------------------------------------------
1873 void SAL_CALL
OleEmbeddedObject::reload(
1874 const uno::Sequence
< beans::PropertyValue
>& lArguments
,
1875 const uno::Sequence
< beans::PropertyValue
>& lObjArgs
)
1876 throw ( lang::IllegalArgumentException
,
1877 embed::WrongStateException
,
1880 uno::RuntimeException
)
1882 // begin wrapping related part ====================
1883 uno::Reference
< embed::XEmbedPersist
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
1884 if ( xWrappedObject
.is() )
1886 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1887 xWrappedObject
->reload( lArguments
, lObjArgs
);
1890 // end wrapping related part ====================
1892 // TODO: use lObjArgs
1894 ::osl::MutexGuard
aGuard( m_aMutex
);
1896 throw lang::DisposedException(); // TODO
1898 if ( m_nObjectState
== -1 )
1900 // the object is still not loaded
1901 throw embed::WrongStateException( OUString( "The object persistence is not initialized!\n" ),
1902 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1905 if ( m_bWaitSaveCompleted
)
1906 throw embed::WrongStateException(
1907 OUString( "The object waits for saveCompleted() call!\n" ),
1908 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1911 // throw away current document
1912 // load new document from current storage
1913 // use meaningfull part of lArguments
1916 //------------------------------------------------------
1917 void SAL_CALL
OleEmbeddedObject::breakLink( const uno::Reference
< embed::XStorage
>& xStorage
,
1918 const OUString
& sEntName
)
1919 throw ( lang::IllegalArgumentException
,
1920 embed::WrongStateException
,
1923 uno::RuntimeException
)
1925 // begin wrapping related part ====================
1926 uno::Reference
< embed::XLinkageSupport
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
1927 if ( xWrappedObject
.is() )
1929 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1930 xWrappedObject
->breakLink( xStorage
, sEntName
);
1933 // end wrapping related part ====================
1935 ::osl::MutexGuard
aGuard( m_aMutex
);
1937 throw lang::DisposedException(); // TODO
1939 if ( !xStorage
.is() )
1940 throw lang::IllegalArgumentException( OUString( "No parent storage is provided!\n" ),
1941 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
1944 if ( sEntName
.isEmpty() )
1945 throw lang::IllegalArgumentException( OUString( "Empty element name is provided!\n" ),
1946 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
1949 // TODO: The object must be at least in Running state;
1950 if ( !m_bIsLink
|| m_nObjectState
== -1 || !m_pOleComponent
)
1952 // it must be a linked initialized object
1953 throw embed::WrongStateException(
1954 OUString( "The object is not a valid linked object!\n" ),
1955 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1959 throw io::IOException(); // TODO: Access denied
1961 if ( m_bWaitSaveCompleted
)
1962 throw embed::WrongStateException(
1963 OUString( "The object waits for saveCompleted() call!\n" ),
1964 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1968 if ( m_pOleComponent
)
1970 // TODO: create an object based on the link
1972 // disconnect the old temporary URL
1973 OUString aOldTempURL
= m_aTempURL
;
1974 m_aTempURL
= OUString();
1976 OleComponent
* pNewOleComponent
= new OleComponent( m_xFactory
, this );
1978 pNewOleComponent
->InitEmbeddedCopyOfLink( m_pOleComponent
);
1980 catch ( const uno::Exception
& )
1982 delete pNewOleComponent
;
1983 if ( !m_aTempURL
.isEmpty() )
1984 KillFile_Impl( m_aTempURL
, m_xFactory
);
1985 m_aTempURL
= aOldTempURL
;
1990 GetRidOfComponent();
1992 catch( const uno::Exception
& )
1994 delete pNewOleComponent
;
1995 if ( !m_aTempURL
.isEmpty() )
1996 KillFile_Impl( m_aTempURL
, m_xFactory
);
1997 m_aTempURL
= aOldTempURL
;
2001 KillFile_Impl( aOldTempURL
, m_xFactory
);
2003 CreateOleComponent_Impl( pNewOleComponent
);
2005 if ( m_xParentStorage
!= xStorage
|| !m_aEntryName
.equals( sEntName
) )
2006 SwitchOwnPersistence( xStorage
, sEntName
);
2008 if ( m_nObjectState
!= embed::EmbedStates::LOADED
)
2010 // TODO: should we activate the new object if the link was activated?
2012 sal_Int32 nTargetState
= m_nObjectState
;
2013 m_nObjectState
= embed::EmbedStates::LOADED
;
2015 if ( m_nObjectState
== embed::EmbedStates::RUNNING
)
2016 m_pOleComponent
->RunObject(); // the object already was in running state, the server must be installed
2017 else // m_nObjectState == embed::EmbedStates::ACTIVE
2019 m_pOleComponent
->RunObject(); // the object already was in running state, the server must be installed
2020 m_pOleComponent
->ExecuteVerb( embed::EmbedVerbs::MS_OLEVERB_OPEN
);
2023 m_nObjectState
= nTargetState
;
2026 m_bIsLink
= sal_False
;
2027 m_aLinkURL
= OUString();
2032 throw io::IOException(); //TODO:
2036 //------------------------------------------------------
2037 sal_Bool SAL_CALL
OleEmbeddedObject::isLink()
2038 throw ( embed::WrongStateException
,
2039 uno::RuntimeException
)
2041 // begin wrapping related part ====================
2042 uno::Reference
< embed::XLinkageSupport
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
2043 if ( xWrappedObject
.is() )
2045 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2046 return xWrappedObject
->isLink();
2048 // end wrapping related part ====================
2050 ::osl::MutexGuard
aGuard( m_aMutex
);
2052 throw lang::DisposedException(); // TODO
2057 //------------------------------------------------------
2058 OUString SAL_CALL
OleEmbeddedObject::getLinkURL()
2059 throw ( embed::WrongStateException
,
2061 uno::RuntimeException
)
2063 // begin wrapping related part ====================
2064 uno::Reference
< embed::XLinkageSupport
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
2065 if ( xWrappedObject
.is() )
2067 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
2068 return xWrappedObject
->getLinkURL();
2070 // end wrapping related part ====================
2072 ::osl::MutexGuard
aGuard( m_aMutex
);
2074 throw lang::DisposedException(); // TODO
2076 if ( m_bWaitSaveCompleted
)
2077 throw embed::WrongStateException(
2078 OUString( "The object waits for saveCompleted() call!\n" ),
2079 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
2082 throw embed::WrongStateException(
2083 OUString( "The object is not a link object!\n" ),
2084 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
2086 // TODO: probably the link URL can be retrieved from OLE
2091 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */