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/ElementModes.hpp>
26 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
27 #include <com/sun/star/embed/Aspects.hpp>
28 #include <com/sun/star/embed/NeedsRunningStateException.hpp>
29 #include <com/sun/star/embed/StateChangeInProgressException.hpp>
30 #include <com/sun/star/embed/EmbedMisc.hpp>
31 #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
32 #include <com/sun/star/io/TempFile.hpp>
33 #include <com/sun/star/io/XSeekable.hpp>
34 #include <com/sun/star/lang/DisposedException.hpp>
35 #include <com/sun/star/beans/NamedValue.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/frame/XLoadable.hpp>
38 #include <com/sun/star/document/XStorageBasedDocument.hpp>
39 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
40 #include <com/sun/star/container/XNameAccess.hpp>
41 #include <com/sun/star/container/XNameContainer.hpp>
42 #include <com/sun/star/system/SystemShellExecute.hpp>
43 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
45 #include <cppuhelper/interfacecontainer.h>
46 #include <comphelper/processfactory.hxx>
47 #include <comphelper/mimeconfighelper.hxx>
48 #include <comphelper/storagehelper.hxx>
51 #include <targetstatecontrol.hxx>
53 #include "ownview.hxx"
56 #include <olecomponent.hxx>
59 using namespace ::com::sun::star
;
63 void OleEmbeddedObject::SwitchComponentToRunningState_Impl()
65 if ( m_pOleComponent
)
69 m_pOleComponent
->RunObject();
71 catch( const embed::UnreachableStateException
& )
76 catch( const embed::WrongStateException
& )
84 throw embed::UnreachableStateException();
89 uno::Sequence
< sal_Int32
> OleEmbeddedObject::GetReachableStatesList_Impl(
90 const uno::Sequence
< embed::VerbDescriptor
>& aVerbList
)
92 uno::Sequence
< sal_Int32
> aStates(2);
93 aStates
[0] = embed::EmbedStates::LOADED
;
94 aStates
[1] = embed::EmbedStates::RUNNING
;
95 for ( sal_Int32 nInd
= 0; nInd
< aVerbList
.getLength(); nInd
++ )
96 if ( aVerbList
[nInd
].VerbID
== embed::EmbedVerbs::MS_OLEVERB_OPEN
)
99 aStates
[2] = embed::EmbedStates::ACTIVE
;
106 uno::Sequence
< sal_Int32
> OleEmbeddedObject::GetIntermediateVerbsSequence_Impl( sal_Int32 nNewState
)
108 SAL_WARN_IF( m_nObjectState
== embed::EmbedStates::LOADED
, "embeddedobj.ole", "Loaded object is switched to running state without verbs using!" );
110 // actually there will be only one verb
111 if ( m_nObjectState
== embed::EmbedStates::RUNNING
&& nNewState
== embed::EmbedStates::ACTIVE
)
113 uno::Sequence
< sal_Int32
> aVerbs( 1 );
114 aVerbs
[0] = embed::EmbedVerbs::MS_OLEVERB_OPEN
;
117 return uno::Sequence
< sal_Int32
>();
121 void OleEmbeddedObject::MoveListeners()
123 if ( m_pInterfaceContainer
)
125 // move state change listeners
127 ::cppu::OInterfaceContainerHelper
* pStateChangeContainer
=
128 m_pInterfaceContainer
->getContainer( cppu::UnoType
<embed::XStateChangeListener
>::get());
129 if ( pStateChangeContainer
!= NULL
)
131 uno::Reference
< embed::XStateChangeBroadcaster
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
132 if ( xWrappedObject
.is() )
134 ::cppu::OInterfaceIteratorHelper
pIterator( *pStateChangeContainer
);
135 while ( pIterator
.hasMoreElements() )
139 xWrappedObject
->addStateChangeListener( static_cast<embed::XStateChangeListener
*>(pIterator
.next()) );
141 catch( const uno::RuntimeException
& )
150 // move event listeners
152 ::cppu::OInterfaceContainerHelper
* pEventContainer
=
153 m_pInterfaceContainer
->getContainer( cppu::UnoType
<document::XEventListener
>::get());
154 if ( pEventContainer
!= NULL
)
156 uno::Reference
< document::XEventBroadcaster
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
157 if ( xWrappedObject
.is() )
159 ::cppu::OInterfaceIteratorHelper
pIterator( *pEventContainer
);
160 while ( pIterator
.hasMoreElements() )
164 xWrappedObject
->addEventListener( static_cast<document::XEventListener
*>(pIterator
.next()) );
166 catch( const uno::RuntimeException
& )
175 // move close listeners
177 ::cppu::OInterfaceContainerHelper
* pCloseContainer
=
178 m_pInterfaceContainer
->getContainer( cppu::UnoType
<util::XCloseListener
>::get());
179 if ( pCloseContainer
!= NULL
)
181 uno::Reference
< util::XCloseBroadcaster
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
182 if ( xWrappedObject
.is() )
184 ::cppu::OInterfaceIteratorHelper
pIterator( *pCloseContainer
);
185 while ( pIterator
.hasMoreElements() )
189 xWrappedObject
->addCloseListener( static_cast<util::XCloseListener
*>(pIterator
.next()) );
191 catch( const uno::RuntimeException
& )
200 delete m_pInterfaceContainer
;
201 m_pInterfaceContainer
= NULL
;
206 uno::Reference
< embed::XStorage
> OleEmbeddedObject::CreateTemporarySubstorage( OUString
& o_aStorageName
)
208 uno::Reference
< embed::XStorage
> xResult
;
210 for ( sal_Int32 nInd
= 0; nInd
< 32000 && !xResult
.is(); nInd
++ )
212 OUString aName
= OUString::number( nInd
) + "TMPSTOR" + m_aEntryName
;
213 if ( !m_xParentStorage
->hasByName( aName
) )
215 xResult
= m_xParentStorage
->openStorageElement( aName
, embed::ElementModes::READWRITE
);
216 o_aStorageName
= aName
;
222 o_aStorageName
.clear();
223 throw uno::RuntimeException();
230 OUString
OleEmbeddedObject::MoveToTemporarySubstream()
233 for ( sal_Int32 nInd
= 0; nInd
< 32000 && aResult
.isEmpty(); nInd
++ )
235 OUString aName
= OUString::number( nInd
) + "TMPSTREAM" + m_aEntryName
;
236 if ( !m_xParentStorage
->hasByName( aName
) )
238 m_xParentStorage
->renameElement( m_aEntryName
, aName
);
243 if ( aResult
.isEmpty() )
244 throw uno::RuntimeException();
250 bool OleEmbeddedObject::TryToConvertToOOo()
252 bool bResult
= false;
254 OUString aStorageName
;
255 OUString aTmpStreamName
;
258 if ( m_pOleComponent
|| m_bReadOnly
)
263 changeState( embed::EmbedStates::LOADED
);
265 // the stream must be seekable
266 uno::Reference
< io::XSeekable
> xSeekable( m_xObjectStream
, uno::UNO_QUERY_THROW
);
267 xSeekable
->seek( 0 );
268 m_aFilterName
= OwnView_Impl::GetFilterNameFromExtentionAndInStream( m_xFactory
, OUString(), m_xObjectStream
->getInputStream() );
270 // use the solution only for OOXML format currently
271 if ( !m_aFilterName
.isEmpty()
272 && ( m_aFilterName
== "Calc MS Excel 2007 XML" || m_aFilterName
== "Impress MS PowerPoint 2007 XML" || m_aFilterName
== "MS Word 2007 XML" ) )
274 uno::Reference
< container::XNameAccess
> xFilterFactory(
275 m_xFactory
->createInstance("com.sun.star.document.FilterFactory"),
276 uno::UNO_QUERY_THROW
);
278 OUString aDocServiceName
;
279 uno::Any aFilterAnyData
= xFilterFactory
->getByName( m_aFilterName
);
280 uno::Sequence
< beans::PropertyValue
> aFilterData
;
281 if ( aFilterAnyData
>>= aFilterData
)
283 for ( sal_Int32 nInd
= 0; nInd
< aFilterData
.getLength(); nInd
++ )
284 if ( aFilterData
[nInd
].Name
== "DocumentService" )
285 aFilterData
[nInd
].Value
>>= aDocServiceName
;
288 if ( !aDocServiceName
.isEmpty() )
291 uno::Sequence
< uno::Any
> aArguments(1);
292 aArguments
[0] <<= beans::NamedValue( OUString( "EmbeddedObject" ), uno::makeAny( true ));
294 uno::Reference
< util::XCloseable
> xDocument( m_xFactory
->createInstanceWithArguments( aDocServiceName
, aArguments
), uno::UNO_QUERY_THROW
);
295 uno::Reference
< frame::XLoadable
> xLoadable( xDocument
, uno::UNO_QUERY_THROW
);
296 uno::Reference
< document::XStorageBasedDocument
> xStorDoc( xDocument
, uno::UNO_QUERY_THROW
);
298 // let the model behave as embedded one
299 uno::Reference
< frame::XModel
> xModel( xDocument
, uno::UNO_QUERY_THROW
);
300 uno::Sequence
< beans::PropertyValue
> aSeq( 1 );
301 aSeq
[0].Name
= "SetEmbedded";
302 aSeq
[0].Value
<<= sal_True
;
303 xModel
->attachResource( OUString(), aSeq
);
305 // load the model from the stream
306 uno::Sequence
< beans::PropertyValue
> aArgs( 5 );
307 aArgs
[0].Name
= "HierarchicalDocumentName";
308 aArgs
[0].Value
<<= m_aEntryName
;
309 aArgs
[1].Name
= "ReadOnly";
310 aArgs
[1].Value
<<= sal_True
;
311 aArgs
[2].Name
= "FilterName";
312 aArgs
[2].Value
<<= m_aFilterName
;
313 aArgs
[3].Name
= "URL";
314 aArgs
[3].Value
<<= OUString( "private:stream" );
315 aArgs
[4].Name
= "InputStream";
316 aArgs
[4].Value
<<= m_xObjectStream
->getInputStream();
318 xSeekable
->seek( 0 );
319 xLoadable
->load( aArgs
);
321 // the model is successfully loaded, create a new storage and store the model to the storage
322 uno::Reference
< embed::XStorage
> xTmpStorage
= CreateTemporarySubstorage( aStorageName
);
323 xStorDoc
->storeToStorage( xTmpStorage
, uno::Sequence
< beans::PropertyValue
>() );
324 xDocument
->close( sal_True
);
325 uno::Reference
< beans::XPropertySet
> xStorProps( xTmpStorage
, uno::UNO_QUERY_THROW
);
327 xStorProps
->getPropertyValue("MediaType") >>= aMediaType
;
328 xTmpStorage
->dispose();
330 // look for the related embedded object factory
331 ::comphelper::MimeConfigurationHelper
aConfigHelper( comphelper::getComponentContext(m_xFactory
) );
332 OUString aEmbedFactory
;
333 if ( !aMediaType
.isEmpty() )
334 aEmbedFactory
= aConfigHelper
.GetFactoryNameByMediaType( aMediaType
);
336 if ( aEmbedFactory
.isEmpty() )
337 throw uno::RuntimeException();
339 uno::Reference
< uno::XInterface
> xFact
= m_xFactory
->createInstance( aEmbedFactory
);
341 uno::Reference
< embed::XEmbedObjectCreator
> xEmbCreator( xFact
, uno::UNO_QUERY_THROW
);
343 // now the object should be adjusted to become the wrapper
345 uno::Reference
< lang::XComponent
> xComp( m_xObjectStream
, uno::UNO_QUERY_THROW
);
347 m_xObjectStream
= uno::Reference
< io::XStream
>();
351 aTmpStreamName
= MoveToTemporarySubstream();
354 m_xParentStorage
->renameElement( aStorageName
, m_aEntryName
);
357 m_xWrappedObject
.set( xEmbCreator
->createInstanceInitFromEntry( m_xParentStorage
, m_aEntryName
, uno::Sequence
< beans::PropertyValue
>(), uno::Sequence
< beans::PropertyValue
>() ), uno::UNO_QUERY_THROW
);
359 bResult
= true; // the change is no more revertable
362 m_xParentStorage
->removeElement( aTmpStreamName
);
364 catch( const uno::Exception
& )
366 // the success of the removing is not so important
371 catch( const uno::Exception
& )
373 // repair the object if necessary
378 if ( !aTmpStreamName
.isEmpty() && aTmpStreamName
!= m_aEntryName
)
381 if ( m_xParentStorage
->hasByName( m_aEntryName
) )
382 m_xParentStorage
->removeElement( m_aEntryName
);
383 m_xParentStorage
->renameElement( aTmpStreamName
, m_aEntryName
);
385 catch ( const uno::Exception
& )
389 } catch( const uno::Exception
& ) {}
391 m_xParentStorage
->dispose(); // ??? the storage has information loss, it should be closed without committing!
392 throw uno::RuntimeException(); // the repairing is not possible
397 m_xObjectStream
= m_xParentStorage
->openStreamElement( m_aEntryName
, m_bReadOnly
? embed::ElementModes::READ
: embed::ElementModes::READWRITE
);
398 m_nObjectState
= embed::EmbedStates::LOADED
;
400 catch( const uno::Exception
& )
404 } catch( const uno::Exception
& ) {}
406 throw uno::RuntimeException(); // the repairing is not possible
408 // no break as designed!
412 if ( !aStorageName
.isEmpty() )
414 m_xParentStorage
->removeElement( aStorageName
);
415 } catch( const uno::Exception
& ) { SAL_WARN( "embeddedobj.ole", "Can not remove temporary storage!" ); }
422 // the conversion was done successfully, now the additional initializations should happen
425 m_xWrappedObject
->setClientSite( m_xClientSite
);
426 if ( m_xParent
.is() )
428 uno::Reference
< container::XChild
> xChild( m_xWrappedObject
, uno::UNO_QUERY
);
430 xChild
->setParent( m_xParent
);
439 void SAL_CALL
OleEmbeddedObject::changeState( sal_Int32 nNewState
)
440 throw ( embed::UnreachableStateException
,
441 embed::WrongStateException
,
443 uno::RuntimeException
, std::exception
)
445 // begin wrapping related part ====================
446 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
447 if ( xWrappedObject
.is() )
449 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
450 xWrappedObject
->changeState( nNewState
);
453 // end wrapping related part ====================
455 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
458 throw lang::DisposedException(); // TODO
460 if ( m_nObjectState
== -1 )
461 throw embed::WrongStateException( "The object has no persistence!",
462 static_cast< ::cppu::OWeakObject
* >(this) );
464 // in case the object is already in requested state
465 if ( m_nObjectState
== nNewState
)
469 if ( m_pOleComponent
)
471 if ( m_nTargetState
!= -1 )
473 // means that the object is currently trying to reach the target state
474 throw embed::StateChangeInProgressException( OUString(),
475 uno::Reference
< uno::XInterface
>(),
479 TargetStateControl_Impl
aControl( m_nTargetState
, nNewState
);
481 // TODO: additional verbs can be a problem, since nobody knows how the object
482 // will behave after activation
484 sal_Int32 nOldState
= m_nObjectState
;
486 StateChangeNotification_Impl( sal_True
, nOldState
, nNewState
);
491 if ( nNewState
== embed::EmbedStates::LOADED
)
493 // This means just closing of the current object
494 // If component can not be closed the object stays in loaded state
495 // and it holds reference to "incomplete" component
496 // If the object is switched to running state later
497 // the component will become "complete"
499 // the loaded state must be set before, because of notifications!
500 m_nObjectState
= nNewState
;
503 VerbExecutionControllerGuard
aVerbGuard( m_aVerbExecutionController
);
504 m_pOleComponent
->CloseObject();
508 StateChangeNotification_Impl( sal_False
, nOldState
, m_nObjectState
);
511 else if ( nNewState
== embed::EmbedStates::RUNNING
|| nNewState
== embed::EmbedStates::ACTIVE
)
513 if ( m_nObjectState
== embed::EmbedStates::LOADED
)
515 // if the target object is in loaded state and a different state is specified
516 // as a new one the object first must be switched to running state.
518 // the component can exist already in nonrunning state
519 // it can be created during loading to detect type of object
520 CreateOleComponentAndLoad_Impl( m_pOleComponent
);
522 SwitchComponentToRunningState_Impl();
523 m_nObjectState
= embed::EmbedStates::RUNNING
;
525 StateChangeNotification_Impl( sal_False
, nOldState
, m_nObjectState
);
528 if ( m_pOleComponent
&& m_bHasSizeToSet
)
532 m_pOleComponent
->SetExtent( m_aSizeToSet
, m_nAspectToSet
);
533 m_bHasSizeToSet
= sal_False
;
535 catch( const uno::Exception
& ) {}
539 if ( m_nObjectState
== nNewState
)
543 // so now the object is either switched from Active to Running state or vise versa
544 // the notification about object state change will be done asynchronously
545 if ( m_nObjectState
== embed::EmbedStates::RUNNING
&& nNewState
== embed::EmbedStates::ACTIVE
)
547 // execute OPEN verb, if object does not reach active state it is an object's problem
549 m_pOleComponent
->ExecuteVerb( embed::EmbedVerbs::MS_OLEVERB_OPEN
);
552 // some objects do not allow to set the size even in running state
553 if ( m_pOleComponent
&& m_bHasSizeToSet
)
557 m_pOleComponent
->SetExtent( m_aSizeToSet
, m_nAspectToSet
);
558 m_bHasSizeToSet
= sal_False
;
560 catch( uno::Exception
& ) {}
564 m_nObjectState
= nNewState
;
566 else if ( m_nObjectState
== embed::EmbedStates::ACTIVE
&& nNewState
== embed::EmbedStates::RUNNING
)
569 m_pOleComponent
->CloseObject();
570 m_pOleComponent
->RunObject(); // Should not fail, the object already was active
572 m_nObjectState
= nNewState
;
576 throw embed::UnreachableStateException();
580 throw embed::UnreachableStateException();
582 catch( uno::Exception
& )
585 StateChangeNotification_Impl( sal_False
, nOldState
, m_nObjectState
);
591 // if it is possible, the object will be converted to OOo format
592 if ( !m_bTriedConversion
)
594 m_bTriedConversion
= true;
595 if ( TryToConvertToOOo() )
597 changeState( nNewState
);
603 throw embed::UnreachableStateException();
608 uno::Sequence
< sal_Int32
> SAL_CALL
OleEmbeddedObject::getReachableStates()
609 throw ( embed::WrongStateException
,
610 uno::RuntimeException
, std::exception
)
612 // begin wrapping related part ====================
613 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
614 if ( xWrappedObject
.is() )
616 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
617 return xWrappedObject
->getReachableStates();
619 // end wrapping related part ====================
621 ::osl::MutexGuard
aGuard( m_aMutex
);
623 throw lang::DisposedException(); // TODO
625 if ( m_nObjectState
== -1 )
626 throw embed::WrongStateException( "The object has no persistence!",
627 static_cast< ::cppu::OWeakObject
* >(this) );
630 if ( m_pOleComponent
)
632 if ( m_nObjectState
== embed::EmbedStates::LOADED
)
634 // the list of supported verbs can be retrieved only when object is in running state
635 throw embed::NeedsRunningStateException(); // TODO:
638 // the list of states can only be guessed based on standard verbs,
639 // since there is no way to detect what additional verbs do
640 return GetReachableStatesList_Impl( m_pOleComponent
->GetVerbList() );
645 return uno::Sequence
< sal_Int32
>();
650 sal_Int32 SAL_CALL
OleEmbeddedObject::getCurrentState()
651 throw ( embed::WrongStateException
,
652 uno::RuntimeException
, std::exception
)
654 // begin wrapping related part ====================
655 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
656 if ( xWrappedObject
.is() )
658 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
659 return xWrappedObject
->getCurrentState();
661 // end wrapping related part ====================
663 ::osl::MutexGuard
aGuard( m_aMutex
);
665 throw lang::DisposedException(); // TODO
667 if ( m_nObjectState
== -1 )
668 throw embed::WrongStateException( "The object has no persistence!",
669 static_cast< ::cppu::OWeakObject
* >(this) );
671 // TODO: Shouldn't we ask object? ( I guess no )
672 return m_nObjectState
;
677 bool lcl_CopyStream(uno::Reference
<io::XInputStream
> xIn
, uno::Reference
<io::XOutputStream
> xOut
)
679 const sal_Int32 nChunkSize
= 4096;
680 uno::Sequence
< sal_Int8
> aData(nChunkSize
);
681 sal_Int32 nTotalRead
= 0;
685 nRead
= xIn
->readBytes(aData
, nChunkSize
);
687 xOut
->writeBytes(aData
);
688 } while (nRead
== nChunkSize
);
689 return nTotalRead
!= 0;
692 //Dump the objects content to a tempfile, just the "CONTENTS" stream if
693 //there is one for non-compound documents, otherwise the whole content.
694 //On success a file is returned which must be removed by the caller
695 OUString
lcl_ExtractObject(::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
> xFactory
,
696 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XStream
> xObjectStream
)
700 // the solution is only active for Unix systems
702 uno::Reference
<beans::XPropertySet
> xNativeTempFile(
703 io::TempFile::create(comphelper::getComponentContext(xFactory
)),
704 uno::UNO_QUERY_THROW
);
705 uno::Reference
< io::XStream
> xStream(xNativeTempFile
, uno::UNO_QUERY_THROW
);
707 uno::Sequence
< uno::Any
> aArgs( 2 );
708 aArgs
[0] <<= xObjectStream
;
709 aArgs
[1] <<= true; // do not create copy
710 uno::Reference
< container::XNameContainer
> xNameContainer(
711 xFactory
->createInstanceWithArguments(
712 OUString("com.sun.star.embed.OLESimpleStorage"),
713 aArgs
), uno::UNO_QUERY_THROW
);
715 uno::Reference
< io::XStream
> xCONTENTS
;
718 xNameContainer
->getByName("CONTENTS") >>= xCONTENTS
;
720 catch (container::NoSuchElementException
const&)
725 bool bCopied
= xCONTENTS
.is() && lcl_CopyStream(xCONTENTS
->getInputStream(), xStream
->getOutputStream());
727 uno::Reference
< io::XSeekable
> xSeekableStor(xObjectStream
, uno::UNO_QUERY
);
728 if (xSeekableStor
.is())
729 xSeekableStor
->seek(0);
732 bCopied
= lcl_CopyStream(xObjectStream
->getInputStream(), xStream
->getOutputStream());
736 xNativeTempFile
->setPropertyValue("RemoveFile",
737 uno::makeAny(sal_False
));
738 uno::Any aUrl
= xNativeTempFile
->getPropertyValue("Uri");
741 xNativeTempFile
= uno::Reference
<beans::XPropertySet
>();
743 uno::Reference
< ucb::XSimpleFileAccess3
> xSimpleFileAccess(
744 ucb::SimpleFileAccess::create( comphelper::getComponentContext(xFactory
) ) );
746 xSimpleFileAccess
->setReadOnly(sUrl
, sal_True
);
750 xNativeTempFile
->setPropertyValue("RemoveFile",
751 uno::makeAny(sal_True
));
755 (void) xObjectStream
;
762 void SAL_CALL
OleEmbeddedObject::doVerb( sal_Int32 nVerbID
)
763 throw ( lang::IllegalArgumentException
,
764 embed::WrongStateException
,
765 embed::UnreachableStateException
,
767 uno::RuntimeException
, std::exception
)
769 // begin wrapping related part ====================
770 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
771 if ( xWrappedObject
.is() )
773 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
774 xWrappedObject
->doVerb( nVerbID
);
777 // end wrapping related part ====================
779 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
781 throw lang::DisposedException(); // TODO
783 if ( m_nObjectState
== -1 )
784 throw embed::WrongStateException( "The object has no persistence!",
785 static_cast< ::cppu::OWeakObject
* >(this) );
788 if ( m_pOleComponent
)
790 sal_Int32 nOldState
= m_nObjectState
;
792 // TODO/LATER detect target state here and do a notification
793 // StateChangeNotification_Impl( sal_True, nOldState, nNewState );
794 if ( m_nObjectState
== embed::EmbedStates::LOADED
)
796 // if the target object is in loaded state
797 // it must be switched to running state to execute verb
799 changeState( embed::EmbedStates::RUNNING
);
804 if ( !m_pOleComponent
)
805 throw uno::RuntimeException();
807 // ==== the STAMPIT related solution =============================
808 m_aVerbExecutionController
.StartControlExecution();
811 m_pOleComponent
->ExecuteVerb( nVerbID
);
813 // ==== the STAMPIT related solution =============================
814 sal_Bool bModifiedOnExecution
= m_aVerbExecutionController
.EndControlExecution_WasModified();
816 // this workaround is implemented for STAMPIT object
817 // if object was modified during verb execution it is saved here
818 if ( bModifiedOnExecution
&& m_pOleComponent
->IsDirty() )
822 catch( uno::Exception
& )
824 // ==== the STAMPIT related solution =============================
825 m_aVerbExecutionController
.EndControlExecution_WasModified();
829 StateChangeNotification_Impl( sal_False
, nOldState
, m_nObjectState
);
839 // the workaround verb to show the object in case no server is available
841 // if it is possible, the object will be converted to OOo format
842 if ( !m_bTriedConversion
)
844 m_bTriedConversion
= true;
845 if ( TryToConvertToOOo() )
847 changeState( embed::EmbedStates::UI_ACTIVE
);
852 if ( !m_pOwnView
&& m_xObjectStream
.is() && m_aFilterName
!= "Text" )
855 uno::Reference
< io::XSeekable
> xSeekable( m_xObjectStream
, uno::UNO_QUERY
);
856 if ( xSeekable
.is() )
857 xSeekable
->seek( 0 );
859 m_pOwnView
= new OwnView_Impl( m_xFactory
, m_xObjectStream
->getInputStream() );
860 m_pOwnView
->acquire();
862 catch( uno::RuntimeException
& )
866 catch (uno::Exception
const& e
)
868 SAL_WARN("embeddedobj.ole", "OleEmbeddedObject::doVerb: "
869 "-9 fallback path: exception caught: " << e
.Message
);
873 if ( m_aFilterName
!= "Text" && (!m_pOwnView
|| !m_pOwnView
->Open()) )
875 //Make a RO copy and see if the OS can find something to at
876 //least display the content for us
877 if (m_aTempDumpURL
.isEmpty())
878 m_aTempDumpURL
= lcl_ExtractObject(m_xFactory
, m_xObjectStream
);
880 if (!m_aTempDumpURL
.isEmpty())
882 uno::Reference
< ::com::sun::star::system::XSystemShellExecute
> xSystemShellExecute(
883 ::com::sun::star::system::SystemShellExecute::create(comphelper::getComponentContext(m_xFactory
)) );
884 xSystemShellExecute
->execute(m_aTempDumpURL
, OUString(), ::com::sun::star::system::SystemShellExecuteFlags::URIS_ONLY
);
887 throw embed::UnreachableStateException();
893 throw embed::UnreachableStateException();
899 uno::Sequence
< embed::VerbDescriptor
> SAL_CALL
OleEmbeddedObject::getSupportedVerbs()
900 throw ( embed::WrongStateException
,
901 uno::RuntimeException
, std::exception
)
903 // begin wrapping related part ====================
904 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
905 if ( xWrappedObject
.is() )
907 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
908 return xWrappedObject
->getSupportedVerbs();
910 // end wrapping related part ====================
912 ::osl::MutexGuard
aGuard( m_aMutex
);
914 throw lang::DisposedException(); // TODO
916 if ( m_nObjectState
== -1 )
917 throw embed::WrongStateException( "The object has no persistence!",
918 static_cast< ::cppu::OWeakObject
* >(this) );
920 if ( m_pOleComponent
)
922 // registry could be used in this case
923 // if ( m_nObjectState == embed::EmbedStates::LOADED )
925 // // the list of supported verbs can be retrieved only when object is in running state
926 // throw embed::NeedsRunningStateException(); // TODO:
929 return m_pOleComponent
->GetVerbList();
934 return uno::Sequence
< embed::VerbDescriptor
>();
939 void SAL_CALL
OleEmbeddedObject::setClientSite(
940 const uno::Reference
< embed::XEmbeddedClient
>& xClient
)
941 throw ( embed::WrongStateException
,
942 uno::RuntimeException
, std::exception
)
944 // begin wrapping related part ====================
945 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
946 if ( xWrappedObject
.is() )
948 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
949 xWrappedObject
->setClientSite( xClient
);
952 // end wrapping related part ====================
954 ::osl::MutexGuard
aGuard( m_aMutex
);
956 throw lang::DisposedException(); // TODO
958 if ( m_xClientSite
!= xClient
)
960 if ( m_nObjectState
!= embed::EmbedStates::LOADED
&& m_nObjectState
!= embed::EmbedStates::RUNNING
)
961 throw embed::WrongStateException(
962 "The client site can not be set currently!",
963 static_cast< ::cppu::OWeakObject
* >(this) );
965 m_xClientSite
= xClient
;
970 uno::Reference
< embed::XEmbeddedClient
> SAL_CALL
OleEmbeddedObject::getClientSite()
971 throw ( embed::WrongStateException
,
972 uno::RuntimeException
, std::exception
)
974 // begin wrapping related part ====================
975 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
976 if ( xWrappedObject
.is() )
978 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
979 return xWrappedObject
->getClientSite();
981 // end wrapping related part ====================
983 ::osl::MutexGuard
aGuard( m_aMutex
);
985 throw lang::DisposedException(); // TODO
987 if ( m_nObjectState
== -1 )
988 throw embed::WrongStateException( "The object has no persistence!",
989 static_cast< ::cppu::OWeakObject
* >(this) );
991 return m_xClientSite
;
995 void SAL_CALL
OleEmbeddedObject::update()
996 throw ( embed::WrongStateException
,
998 uno::RuntimeException
, std::exception
)
1000 // begin wrapping related part ====================
1001 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
1002 if ( xWrappedObject
.is() )
1004 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1005 xWrappedObject
->update();
1008 // end wrapping related part ====================
1010 ::osl::MutexGuard
aGuard( m_aMutex
);
1012 throw lang::DisposedException(); // TODO
1014 if ( m_nObjectState
== -1 )
1015 throw embed::WrongStateException( "The object has no persistence!",
1016 static_cast< ::cppu::OWeakObject
* >(this) );
1018 if ( m_nUpdateMode
== embed::EmbedUpdateModes::EXPLICIT_UPDATE
)
1020 // TODO: update view representation
1024 // the object must be up to date
1025 SAL_WARN_IF( m_nUpdateMode
!= embed::EmbedUpdateModes::ALWAYS_UPDATE
, "embeddedobj.ole", "Unknown update mode!" );
1030 void SAL_CALL
OleEmbeddedObject::setUpdateMode( sal_Int32 nMode
)
1031 throw ( embed::WrongStateException
,
1032 uno::RuntimeException
, std::exception
)
1034 // begin wrapping related part ====================
1035 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
1036 if ( xWrappedObject
.is() )
1038 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1039 xWrappedObject
->setUpdateMode( nMode
);
1042 // end wrapping related part ====================
1044 ::osl::MutexGuard
aGuard( m_aMutex
);
1046 throw lang::DisposedException(); // TODO
1048 if ( m_nObjectState
== -1 )
1049 throw embed::WrongStateException( "The object has no persistence!",
1050 static_cast< ::cppu::OWeakObject
* >(this) );
1052 OSL_ENSURE( nMode
== embed::EmbedUpdateModes::ALWAYS_UPDATE
1053 || nMode
== embed::EmbedUpdateModes::EXPLICIT_UPDATE
,
1054 "Unknown update mode!\n" );
1055 m_nUpdateMode
= nMode
;
1059 sal_Int64 SAL_CALL
OleEmbeddedObject::getStatus( sal_Int64
1062 throw ( embed::WrongStateException
,
1063 uno::RuntimeException
, std::exception
)
1065 // begin wrapping related part ====================
1066 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
1067 if ( xWrappedObject
.is() )
1069 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1070 return xWrappedObject
->getStatus( nAspect
);
1072 // end wrapping related part ====================
1074 ::osl::MutexGuard
aGuard( m_aMutex
);
1076 throw lang::DisposedException(); // TODO
1078 if ( m_nObjectState
== -1 )
1079 throw embed::WrongStateException( "The object must be in running state!",
1080 static_cast< ::cppu::OWeakObject
* >(this) );
1082 sal_Int64 nResult
= 0;
1085 if ( m_bGotStatus
&& m_nStatusAspect
== nAspect
)
1086 nResult
= m_nStatus
;
1087 else if ( m_pOleComponent
)
1090 m_nStatus
= m_pOleComponent
->GetMiscStatus( nAspect
);
1091 m_nStatusAspect
= nAspect
;
1092 m_bGotStatus
= sal_True
;
1093 nResult
= m_nStatus
;
1097 // this implementation needs size to be provided after object loading/creating to work in optimal way
1098 return ( nResult
| embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD
);
1102 void SAL_CALL
OleEmbeddedObject::setContainerName( const OUString
& sName
)
1103 throw ( uno::RuntimeException
, std::exception
)
1105 // begin wrapping related part ====================
1106 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
1107 if ( xWrappedObject
.is() )
1109 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1110 xWrappedObject
->setContainerName( sName
);
1113 // end wrapping related part ====================
1115 ::osl::MutexGuard
aGuard( m_aMutex
);
1117 throw lang::DisposedException(); // TODO
1119 m_aContainerName
= sName
;
1123 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */