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 <olecomponent.hxx>
55 #include "ownview.hxx"
57 using namespace ::com::sun::star
;
60 //----------------------------------------------
61 void OleEmbeddedObject::SwitchComponentToRunningState_Impl()
63 if ( m_pOleComponent
)
67 m_pOleComponent
->RunObject();
69 catch( const embed::UnreachableStateException
& )
74 catch( const embed::WrongStateException
& )
82 throw embed::UnreachableStateException();
86 //----------------------------------------------
87 uno::Sequence
< sal_Int32
> OleEmbeddedObject::GetReachableStatesList_Impl(
88 const uno::Sequence
< embed::VerbDescriptor
>& aVerbList
)
90 uno::Sequence
< sal_Int32
> aStates(2);
91 aStates
[0] = embed::EmbedStates::LOADED
;
92 aStates
[1] = embed::EmbedStates::RUNNING
;
93 for ( sal_Int32 nInd
= 0; nInd
< aVerbList
.getLength(); nInd
++ )
94 if ( aVerbList
[nInd
].VerbID
== embed::EmbedVerbs::MS_OLEVERB_OPEN
)
97 aStates
[2] = embed::EmbedStates::ACTIVE
;
103 //----------------------------------------------
104 uno::Sequence
< sal_Int32
> OleEmbeddedObject::GetIntermediateVerbsSequence_Impl( sal_Int32 nNewState
)
106 SAL_WARN_IF( m_nObjectState
== embed::EmbedStates::LOADED
, "embeddedobj.ole", "Loaded object is switched to running state without verbs using!" );
108 // actually there will be only one verb
109 if ( m_nObjectState
== embed::EmbedStates::RUNNING
&& nNewState
== embed::EmbedStates::ACTIVE
)
111 uno::Sequence
< sal_Int32
> aVerbs( 1 );
112 aVerbs
[0] = embed::EmbedVerbs::MS_OLEVERB_OPEN
;
115 return uno::Sequence
< sal_Int32
>();
118 //----------------------------------------------
119 void OleEmbeddedObject::MoveListeners()
121 if ( m_pInterfaceContainer
)
123 // move state change listeners
125 ::cppu::OInterfaceContainerHelper
* pStateChangeContainer
=
126 m_pInterfaceContainer
->getContainer( ::getCppuType( ( const uno::Reference
< embed::XStateChangeListener
>*) NULL
) );
127 if ( pStateChangeContainer
!= NULL
)
129 uno::Reference
< embed::XStateChangeBroadcaster
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
130 if ( xWrappedObject
.is() )
132 ::cppu::OInterfaceIteratorHelper
pIterator( *pStateChangeContainer
);
133 while ( pIterator
.hasMoreElements() )
137 xWrappedObject
->addStateChangeListener( (embed::XStateChangeListener
*)pIterator
.next() );
139 catch( const uno::RuntimeException
& )
148 // move event listeners
150 ::cppu::OInterfaceContainerHelper
* pEventContainer
=
151 m_pInterfaceContainer
->getContainer( ::getCppuType( ( const uno::Reference
< document::XEventListener
>*) NULL
) );
152 if ( pEventContainer
!= NULL
)
154 uno::Reference
< document::XEventBroadcaster
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
155 if ( xWrappedObject
.is() )
157 ::cppu::OInterfaceIteratorHelper
pIterator( *pEventContainer
);
158 while ( pIterator
.hasMoreElements() )
162 xWrappedObject
->addEventListener( (document::XEventListener
*)pIterator
.next() );
164 catch( const uno::RuntimeException
& )
173 // move close listeners
175 ::cppu::OInterfaceContainerHelper
* pCloseContainer
=
176 m_pInterfaceContainer
->getContainer( ::getCppuType( ( const uno::Reference
< util::XCloseListener
>*) NULL
) );
177 if ( pCloseContainer
!= NULL
)
179 uno::Reference
< util::XCloseBroadcaster
> xWrappedObject( m_xWrappedObject
, uno::UNO_QUERY
);
180 if ( xWrappedObject
.is() )
182 ::cppu::OInterfaceIteratorHelper
pIterator( *pCloseContainer
);
183 while ( pIterator
.hasMoreElements() )
187 xWrappedObject
->addCloseListener( (util::XCloseListener
*)pIterator
.next() );
189 catch( const uno::RuntimeException
& )
198 delete m_pInterfaceContainer
;
199 m_pInterfaceContainer
= NULL
;
203 //----------------------------------------------
204 uno::Reference
< embed::XStorage
> OleEmbeddedObject::CreateTemporarySubstorage( OUString
& o_aStorageName
)
206 uno::Reference
< embed::XStorage
> xResult
;
208 for ( sal_Int32 nInd
= 0; nInd
< 32000 && !xResult
.is(); nInd
++ )
210 OUString aName
= OUString::number( nInd
) + "TMPSTOR" + m_aEntryName
;
211 if ( !m_xParentStorage
->hasByName( aName
) )
213 xResult
= m_xParentStorage
->openStorageElement( aName
, embed::ElementModes::READWRITE
);
214 o_aStorageName
= aName
;
220 o_aStorageName
= OUString();
221 throw uno::RuntimeException();
227 //----------------------------------------------
228 OUString
OleEmbeddedObject::MoveToTemporarySubstream()
231 for ( sal_Int32 nInd
= 0; nInd
< 32000 && aResult
.isEmpty(); nInd
++ )
233 OUString aName
= OUString::number( nInd
) + "TMPSTREAM" + m_aEntryName
;
234 if ( !m_xParentStorage
->hasByName( aName
) )
236 m_xParentStorage
->renameElement( m_aEntryName
, aName
);
241 if ( aResult
.isEmpty() )
242 throw uno::RuntimeException();
247 //----------------------------------------------
248 sal_Bool
OleEmbeddedObject::TryToConvertToOOo()
250 sal_Bool bResult
= sal_False
;
252 OUString aStorageName
;
253 OUString aTmpStreamName
;
256 if ( m_pOleComponent
|| m_bReadOnly
)
261 changeState( embed::EmbedStates::LOADED
);
263 // the stream must be seekable
264 uno::Reference
< io::XSeekable
> xSeekable( m_xObjectStream
, uno::UNO_QUERY_THROW
);
265 xSeekable
->seek( 0 );
266 OUString aFilterName
= OwnView_Impl::GetFilterNameFromExtentionAndInStream( m_xFactory
, OUString(), m_xObjectStream
->getInputStream() );
268 // use the solution only for OOXML format currently
269 if ( !aFilterName
.isEmpty()
270 && ( aFilterName
== "Calc MS Excel 2007 XML" || aFilterName
== "Impress MS PowerPoint 2007 XML" || aFilterName
== "MS Word 2007 XML" ) )
272 uno::Reference
< container::XNameAccess
> xFilterFactory(
273 m_xFactory
->createInstance("com.sun.star.document.FilterFactory"),
274 uno::UNO_QUERY_THROW
);
276 OUString aDocServiceName
;
277 uno::Any aFilterAnyData
= xFilterFactory
->getByName( aFilterName
);
278 uno::Sequence
< beans::PropertyValue
> aFilterData
;
279 if ( aFilterAnyData
>>= aFilterData
)
281 for ( sal_Int32 nInd
= 0; nInd
< aFilterData
.getLength(); nInd
++ )
282 if ( aFilterData
[nInd
].Name
== "DocumentService" )
283 aFilterData
[nInd
].Value
>>= aDocServiceName
;
286 if ( !aDocServiceName
.isEmpty() )
289 uno::Sequence
< uno::Any
> aArguments(1);
290 aArguments
[0] <<= beans::NamedValue( OUString( "EmbeddedObject" ), uno::makeAny( (sal_Bool
)sal_True
));
292 uno::Reference
< util::XCloseable
> xDocument( m_xFactory
->createInstanceWithArguments( aDocServiceName
, aArguments
), uno::UNO_QUERY_THROW
);
293 uno::Reference
< frame::XLoadable
> xLoadable( xDocument
, uno::UNO_QUERY_THROW
);
294 uno::Reference
< document::XStorageBasedDocument
> xStorDoc( xDocument
, uno::UNO_QUERY_THROW
);
296 // let the model behave as embedded one
297 uno::Reference
< frame::XModel
> xModel( xDocument
, uno::UNO_QUERY_THROW
);
298 uno::Sequence
< beans::PropertyValue
> aSeq( 1 );
299 aSeq
[0].Name
= "SetEmbedded";
300 aSeq
[0].Value
<<= sal_True
;
301 xModel
->attachResource( OUString(), aSeq
);
303 // load the model from the stream
304 uno::Sequence
< beans::PropertyValue
> aArgs( 5 );
305 aArgs
[0].Name
= "HierarchicalDocumentName";
306 aArgs
[0].Value
<<= m_aEntryName
;
307 aArgs
[1].Name
= "ReadOnly";
308 aArgs
[1].Value
<<= sal_True
;
309 aArgs
[2].Name
= "FilterName";
310 aArgs
[2].Value
<<= aFilterName
;
311 aArgs
[3].Name
= "URL";
312 aArgs
[3].Value
<<= OUString( "private:stream" );
313 aArgs
[4].Name
= "InputStream";
314 aArgs
[4].Value
<<= m_xObjectStream
->getInputStream();
316 xSeekable
->seek( 0 );
317 xLoadable
->load( aArgs
);
319 // the model is successfully loaded, create a new storage and store the model to the storage
320 uno::Reference
< embed::XStorage
> xTmpStorage
= CreateTemporarySubstorage( aStorageName
);
321 xStorDoc
->storeToStorage( xTmpStorage
, uno::Sequence
< beans::PropertyValue
>() );
322 xDocument
->close( sal_True
);
323 uno::Reference
< beans::XPropertySet
> xStorProps( xTmpStorage
, uno::UNO_QUERY_THROW
);
325 xStorProps
->getPropertyValue("MediaType") >>= aMediaType
;
326 xTmpStorage
->dispose();
328 // look for the related embedded object factory
329 ::comphelper::MimeConfigurationHelper
aConfigHelper( comphelper::getComponentContext(m_xFactory
) );
330 OUString aEmbedFactory
;
331 if ( !aMediaType
.isEmpty() )
332 aEmbedFactory
= aConfigHelper
.GetFactoryNameByMediaType( aMediaType
);
334 if ( aEmbedFactory
.isEmpty() )
335 throw uno::RuntimeException();
337 uno::Reference
< uno::XInterface
> xFact
= m_xFactory
->createInstance( aEmbedFactory
);
339 uno::Reference
< embed::XEmbedObjectCreator
> xEmbCreator( xFact
, uno::UNO_QUERY_THROW
);
341 // now the object should be adjusted to become the wrapper
343 uno::Reference
< lang::XComponent
> xComp( m_xObjectStream
, uno::UNO_QUERY_THROW
);
345 m_xObjectStream
= uno::Reference
< io::XStream
>();
349 aTmpStreamName
= MoveToTemporarySubstream();
352 m_xParentStorage
->renameElement( aStorageName
, m_aEntryName
);
355 m_xWrappedObject
.set( xEmbCreator
->createInstanceInitFromEntry( m_xParentStorage
, m_aEntryName
, uno::Sequence
< beans::PropertyValue
>(), uno::Sequence
< beans::PropertyValue
>() ), uno::UNO_QUERY_THROW
);
357 bResult
= sal_True
; // the change is no more revertable
360 m_xParentStorage
->removeElement( aTmpStreamName
);
362 catch( const uno::Exception
& )
364 // the success of the removing is not so important
369 catch( const uno::Exception
& )
371 // repair the object if necessary
376 if ( !aTmpStreamName
.isEmpty() && aTmpStreamName
!= m_aEntryName
)
379 if ( m_xParentStorage
->hasByName( m_aEntryName
) )
380 m_xParentStorage
->removeElement( m_aEntryName
);
381 m_xParentStorage
->renameElement( aTmpStreamName
, m_aEntryName
);
383 catch ( const uno::Exception
& )
387 } catch( const uno::Exception
& ) {}
389 m_xParentStorage
->dispose(); // ??? the storage has information loss, it should be closed without commiting!
390 throw uno::RuntimeException(); // the repairing is not possible
395 m_xObjectStream
= m_xParentStorage
->openStreamElement( m_aEntryName
, m_bReadOnly
? embed::ElementModes::READ
: embed::ElementModes::READWRITE
);
396 m_nObjectState
= embed::EmbedStates::LOADED
;
398 catch( const uno::Exception
& )
402 } catch( const uno::Exception
& ) {}
404 throw uno::RuntimeException(); // the repairing is not possible
406 // no break as designed!
410 if ( !aStorageName
.isEmpty() )
412 m_xParentStorage
->removeElement( aStorageName
);
413 } catch( const uno::Exception
& ) { SAL_WARN( "embeddedobj.ole", "Can not remove temporary storage!" ); }
420 // the conversion was done successfully, now the additional initializations should happen
423 m_xWrappedObject
->setClientSite( m_xClientSite
);
424 if ( m_xParent
.is() )
426 uno::Reference
< container::XChild
> xChild( m_xWrappedObject
, uno::UNO_QUERY
);
428 xChild
->setParent( m_xParent
);
436 //----------------------------------------------
437 void SAL_CALL
OleEmbeddedObject::changeState( sal_Int32 nNewState
)
438 throw ( embed::UnreachableStateException
,
439 embed::WrongStateException
,
441 uno::RuntimeException
)
443 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::changeState" );
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( OUString( "The object has no persistence!\n" ),
462 uno::Reference
< uno::XInterface
>( 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
);
592 throw embed::UnreachableStateException();
596 //----------------------------------------------
597 uno::Sequence
< sal_Int32
> SAL_CALL
OleEmbeddedObject::getReachableStates()
598 throw ( embed::WrongStateException
,
599 uno::RuntimeException
)
601 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::getReachableStates" );
603 // begin wrapping related part ====================
604 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
605 if ( xWrappedObject
.is() )
607 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
608 return xWrappedObject
->getReachableStates();
610 // end wrapping related part ====================
612 ::osl::MutexGuard
aGuard( m_aMutex
);
614 throw lang::DisposedException(); // TODO
616 if ( m_nObjectState
== -1 )
617 throw embed::WrongStateException( OUString( "The object has no persistence!\n" ),
618 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
621 if ( m_pOleComponent
)
623 if ( m_nObjectState
== embed::EmbedStates::LOADED
)
625 // the list of supported verbs can be retrieved only when object is in running state
626 throw embed::NeedsRunningStateException(); // TODO:
629 // the list of states can only be guessed based on standard verbs,
630 // since there is no way to detect what additional verbs do
631 return GetReachableStatesList_Impl( m_pOleComponent
->GetVerbList() );
636 return uno::Sequence
< sal_Int32
>();
640 //----------------------------------------------
641 sal_Int32 SAL_CALL
OleEmbeddedObject::getCurrentState()
642 throw ( embed::WrongStateException
,
643 uno::RuntimeException
)
645 // begin wrapping related part ====================
646 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
647 if ( xWrappedObject
.is() )
649 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
650 return xWrappedObject
->getCurrentState();
652 // end wrapping related part ====================
654 ::osl::MutexGuard
aGuard( m_aMutex
);
656 throw lang::DisposedException(); // TODO
658 if ( m_nObjectState
== -1 )
659 throw embed::WrongStateException( OUString( "The object has no persistence!\n" ),
660 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
662 // TODO: Shouldn't we ask object? ( I guess no )
663 return m_nObjectState
;
668 bool lcl_CopyStream(uno::Reference
<io::XInputStream
> xIn
, uno::Reference
<io::XOutputStream
> xOut
)
670 const sal_Int32 nChunkSize
= 4096;
671 uno::Sequence
< sal_Int8
> aData(nChunkSize
);
672 sal_Int32 nTotalRead
= 0;
676 nRead
= xIn
->readBytes(aData
, nChunkSize
);
678 xOut
->writeBytes(aData
);
679 } while (nRead
== nChunkSize
);
680 return nTotalRead
!= 0;
683 //Dump the objects content to a tempfile, just the "CONTENTS" stream if
684 //there is one for non-compound documents, otherwise the whole content.
685 //On success a file is returned which must be removed by the caller
686 OUString
lcl_ExtractObject(::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
> xFactory
,
687 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XStream
> xObjectStream
)
691 // the solution is only active for Unix systems
693 uno::Reference
<beans::XPropertySet
> xNativeTempFile(
694 io::TempFile::create(comphelper::getComponentContext(xFactory
)),
695 uno::UNO_QUERY_THROW
);
696 uno::Reference
< io::XStream
> xStream(xNativeTempFile
, uno::UNO_QUERY_THROW
);
698 uno::Sequence
< uno::Any
> aArgs( 2 );
699 aArgs
[0] <<= xObjectStream
;
700 aArgs
[1] <<= (sal_Bool
)sal_True
; // do not create copy
701 uno::Reference
< container::XNameContainer
> xNameContainer(
702 xFactory
->createInstanceWithArguments(
703 OUString("com.sun.star.embed.OLESimpleStorage"),
704 aArgs
), uno::UNO_QUERY_THROW
);
706 uno::Reference
< io::XStream
> xCONTENTS
;
709 xNameContainer
->getByName("CONTENTS") >>= xCONTENTS
;
711 catch (container::NoSuchElementException
const&)
716 sal_Bool bCopied
= xCONTENTS
.is() && lcl_CopyStream(xCONTENTS
->getInputStream(), xStream
->getOutputStream());
718 uno::Reference
< io::XSeekable
> xSeekableStor(xObjectStream
, uno::UNO_QUERY
);
719 if (xSeekableStor
.is())
720 xSeekableStor
->seek(0);
723 bCopied
= lcl_CopyStream(xObjectStream
->getInputStream(), xStream
->getOutputStream());
727 xNativeTempFile
->setPropertyValue("RemoveFile",
728 uno::makeAny(sal_False
));
729 uno::Any aUrl
= xNativeTempFile
->getPropertyValue("Uri");
732 xNativeTempFile
= uno::Reference
<beans::XPropertySet
>();
734 uno::Reference
< ucb::XSimpleFileAccess3
> xSimpleFileAccess(
735 ucb::SimpleFileAccess::create( comphelper::getComponentContext(xFactory
) ) );
737 xSimpleFileAccess
->setReadOnly(sUrl
, sal_True
);
741 xNativeTempFile
->setPropertyValue("RemoveFile",
742 uno::makeAny(sal_True
));
746 (void) xObjectStream
;
752 //----------------------------------------------
753 void SAL_CALL
OleEmbeddedObject::doVerb( sal_Int32 nVerbID
)
754 throw ( lang::IllegalArgumentException
,
755 embed::WrongStateException
,
756 embed::UnreachableStateException
,
758 uno::RuntimeException
)
760 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::doVerb" );
762 // begin wrapping related part ====================
763 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
764 if ( xWrappedObject
.is() )
766 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
767 xWrappedObject
->doVerb( nVerbID
);
770 // end wrapping related part ====================
772 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
774 throw lang::DisposedException(); // TODO
776 if ( m_nObjectState
== -1 )
777 throw embed::WrongStateException( OUString( "The object has no persistence!\n" ),
778 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
781 if ( m_pOleComponent
)
783 sal_Int32 nOldState
= m_nObjectState
;
785 // TODO/LATER detect target state here and do a notification
786 // StateChangeNotification_Impl( sal_True, nOldState, nNewState );
787 if ( m_nObjectState
== embed::EmbedStates::LOADED
)
789 // if the target object is in loaded state
790 // it must be switched to running state to execute verb
792 changeState( embed::EmbedStates::RUNNING
);
797 if ( !m_pOleComponent
)
798 throw uno::RuntimeException();
800 // ==== the STAMPIT related solution =============================
801 m_aVerbExecutionController
.StartControlExecution();
802 // ===============================================================
804 m_pOleComponent
->ExecuteVerb( nVerbID
);
806 // ==== the STAMPIT related solution =============================
807 sal_Bool bModifiedOnExecution
= m_aVerbExecutionController
.EndControlExecution_WasModified();
809 // this workaround is implemented for STAMPIT object
810 // if object was modified during verb execution it is saved here
811 if ( bModifiedOnExecution
&& m_pOleComponent
->IsDirty() )
813 // ===============================================================
815 catch( uno::Exception
& )
817 // ==== the STAMPIT related solution =============================
818 m_aVerbExecutionController
.EndControlExecution_WasModified();
819 // ===============================================================
822 StateChangeNotification_Impl( sal_False
, nOldState
, m_nObjectState
);
832 // the workaround verb to show the object in case no server is available
834 // if it is possible, the object will be converted to OOo format
835 if ( !m_bTriedConversion
)
837 m_bTriedConversion
= sal_True
;
838 if ( TryToConvertToOOo() )
840 changeState( embed::EmbedStates::UI_ACTIVE
);
845 if ( !m_pOwnView
&& m_xObjectStream
.is() )
848 uno::Reference
< io::XSeekable
> xSeekable( m_xObjectStream
, uno::UNO_QUERY
);
849 if ( xSeekable
.is() )
850 xSeekable
->seek( 0 );
852 m_pOwnView
= new OwnView_Impl( m_xFactory
, m_xObjectStream
->getInputStream() );
853 m_pOwnView
->acquire();
855 catch( uno::RuntimeException
& )
859 catch (uno::Exception
const& e
)
861 SAL_WARN("embeddedobj.ole", "OleEmbeddedObject::doVerb: "
862 "-9 fallback path: exception caught: " << e
.Message
);
866 if ( !m_pOwnView
|| !m_pOwnView
->Open() )
868 //Make a RO copy and see if the OS can find something to at
869 //least display the content for us
870 if (m_aTempDumpURL
.isEmpty())
871 m_aTempDumpURL
= lcl_ExtractObject(m_xFactory
, m_xObjectStream
);
873 if (!m_aTempDumpURL
.isEmpty())
875 uno::Reference
< ::com::sun::star::system::XSystemShellExecute
> xSystemShellExecute(
876 ::com::sun::star::system::SystemShellExecute::create(comphelper::getComponentContext(m_xFactory
)) );
877 xSystemShellExecute
->execute(m_aTempDumpURL
, OUString(), ::com::sun::star::system::SystemShellExecuteFlags::URIS_ONLY
);
880 throw embed::UnreachableStateException();
886 throw embed::UnreachableStateException();
891 //----------------------------------------------
892 uno::Sequence
< embed::VerbDescriptor
> SAL_CALL
OleEmbeddedObject::getSupportedVerbs()
893 throw ( embed::WrongStateException
,
894 uno::RuntimeException
)
896 SAL_INFO( "embeddedobj.ole", "embeddedobj (mv76033) OleEmbeddedObject::getSupportedVerb" );
898 // begin wrapping related part ====================
899 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
900 if ( xWrappedObject
.is() )
902 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
903 return xWrappedObject
->getSupportedVerbs();
905 // end wrapping related part ====================
907 ::osl::MutexGuard
aGuard( m_aMutex
);
909 throw lang::DisposedException(); // TODO
911 if ( m_nObjectState
== -1 )
912 throw embed::WrongStateException( OUString( "The object has no persistence!\n" ),
913 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
915 if ( m_pOleComponent
)
917 // registry could be used in this case
918 // if ( m_nObjectState == embed::EmbedStates::LOADED )
920 // // the list of supported verbs can be retrieved only when object is in running state
921 // throw embed::NeedsRunningStateException(); // TODO:
924 return m_pOleComponent
->GetVerbList();
929 return uno::Sequence
< embed::VerbDescriptor
>();
933 //----------------------------------------------
934 void SAL_CALL
OleEmbeddedObject::setClientSite(
935 const uno::Reference
< embed::XEmbeddedClient
>& xClient
)
936 throw ( embed::WrongStateException
,
937 uno::RuntimeException
)
939 // begin wrapping related part ====================
940 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
941 if ( xWrappedObject
.is() )
943 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
944 xWrappedObject
->setClientSite( xClient
);
947 // end wrapping related part ====================
949 ::osl::MutexGuard
aGuard( m_aMutex
);
951 throw lang::DisposedException(); // TODO
953 if ( m_xClientSite
!= xClient
)
955 if ( m_nObjectState
!= embed::EmbedStates::LOADED
&& m_nObjectState
!= embed::EmbedStates::RUNNING
)
956 throw embed::WrongStateException(
957 OUString( "The client site can not be set currently!\n" ),
958 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
960 m_xClientSite
= xClient
;
964 //----------------------------------------------
965 uno::Reference
< embed::XEmbeddedClient
> SAL_CALL
OleEmbeddedObject::getClientSite()
966 throw ( embed::WrongStateException
,
967 uno::RuntimeException
)
969 // begin wrapping related part ====================
970 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
971 if ( xWrappedObject
.is() )
973 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
974 return xWrappedObject
->getClientSite();
976 // end wrapping related part ====================
978 ::osl::MutexGuard
aGuard( m_aMutex
);
980 throw lang::DisposedException(); // TODO
982 if ( m_nObjectState
== -1 )
983 throw embed::WrongStateException( OUString( "The object has no persistence!\n" ),
984 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
986 return m_xClientSite
;
989 //----------------------------------------------
990 void SAL_CALL
OleEmbeddedObject::update()
991 throw ( embed::WrongStateException
,
993 uno::RuntimeException
)
995 // begin wrapping related part ====================
996 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
997 if ( xWrappedObject
.is() )
999 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1000 xWrappedObject
->update();
1003 // end wrapping related part ====================
1005 ::osl::MutexGuard
aGuard( m_aMutex
);
1007 throw lang::DisposedException(); // TODO
1009 if ( m_nObjectState
== -1 )
1010 throw embed::WrongStateException( OUString( "The object has no persistence!\n" ),
1011 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1013 if ( m_nUpdateMode
== embed::EmbedUpdateModes::EXPLICIT_UPDATE
)
1015 // TODO: update view representation
1019 // the object must be up to date
1020 SAL_WARN_IF( m_nUpdateMode
!= embed::EmbedUpdateModes::ALWAYS_UPDATE
, "embeddedobj.ole", "Unknown update mode!" );
1024 //----------------------------------------------
1025 void SAL_CALL
OleEmbeddedObject::setUpdateMode( sal_Int32 nMode
)
1026 throw ( embed::WrongStateException
,
1027 uno::RuntimeException
)
1029 // begin wrapping related part ====================
1030 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
1031 if ( xWrappedObject
.is() )
1033 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1034 xWrappedObject
->setUpdateMode( nMode
);
1037 // end wrapping related part ====================
1039 ::osl::MutexGuard
aGuard( m_aMutex
);
1041 throw lang::DisposedException(); // TODO
1043 if ( m_nObjectState
== -1 )
1044 throw embed::WrongStateException( OUString( "The object has no persistence!\n" ),
1045 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1047 OSL_ENSURE( nMode
== embed::EmbedUpdateModes::ALWAYS_UPDATE
1048 || nMode
== embed::EmbedUpdateModes::EXPLICIT_UPDATE
,
1049 "Unknown update mode!\n" );
1050 m_nUpdateMode
= nMode
;
1053 //----------------------------------------------
1054 sal_Int64 SAL_CALL
OleEmbeddedObject::getStatus( sal_Int64
1057 throw ( embed::WrongStateException
,
1058 uno::RuntimeException
)
1060 // begin wrapping related part ====================
1061 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
1062 if ( xWrappedObject
.is() )
1064 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1065 return xWrappedObject
->getStatus( nAspect
);
1067 // end wrapping related part ====================
1069 ::osl::MutexGuard
aGuard( m_aMutex
);
1071 throw lang::DisposedException(); // TODO
1073 if ( m_nObjectState
== -1 )
1074 throw embed::WrongStateException( OUString( "The object must be in running state!\n" ),
1075 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ) );
1077 sal_Int64 nResult
= 0;
1080 if ( m_bGotStatus
&& m_nStatusAspect
== nAspect
)
1081 nResult
= m_nStatus
;
1082 else if ( m_pOleComponent
)
1085 m_nStatus
= m_pOleComponent
->GetMiscStatus( nAspect
);
1086 m_nStatusAspect
= nAspect
;
1087 m_bGotStatus
= sal_True
;
1088 nResult
= m_nStatus
;
1092 // this implementation needs size to be provided after object loading/creating to work in optimal way
1093 return ( nResult
| embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD
);
1096 //----------------------------------------------
1097 void SAL_CALL
OleEmbeddedObject::setContainerName( const OUString
& sName
)
1098 throw ( uno::RuntimeException
)
1100 // begin wrapping related part ====================
1101 uno::Reference
< embed::XEmbeddedObject
> xWrappedObject
= m_xWrappedObject
;
1102 if ( xWrappedObject
.is() )
1104 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1105 xWrappedObject
->setContainerName( sName
);
1108 // end wrapping related part ====================
1110 ::osl::MutexGuard
aGuard( m_aMutex
);
1112 throw lang::DisposedException(); // TODO
1114 m_aContainerName
= sName
;
1118 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */