update dev300-m58
[ooovba.git] / embeddedobj / source / msole / oleembed.cxx
blob28a1aa9b02edcf68d2ca72d76c1163b8f127a7f1
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: oleembed.cxx,v $
10 * $Revision: 1.24 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_embeddedobj.hxx"
34 #include <oleembobj.hxx>
35 #include <com/sun/star/embed/EmbedStates.hpp>
36 #include <com/sun/star/embed/EmbedVerbs.hpp>
37 #include <com/sun/star/embed/EntryInitModes.hpp>
38 #include <com/sun/star/embed/XStorage.hpp>
39 #include <com/sun/star/embed/ElementModes.hpp>
40 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
41 #include <com/sun/star/embed/Aspects.hpp>
42 #include <com/sun/star/embed/NeedsRunningStateException.hpp>
43 #include <com/sun/star/embed/StateChangeInProgressException.hpp>
44 #include <com/sun/star/embed/EmbedMisc.hpp>
45 #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
46 #include <com/sun/star/io/XSeekable.hpp>
47 #include <com/sun/star/lang/DisposedException.hpp>
48 #include <com/sun/star/beans/NamedValue.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/frame/XLoadable.hpp>
51 #include <com/sun/star/document/XStorageBasedDocument.hpp>
53 #include <rtl/logfile.hxx>
54 #include <cppuhelper/interfacecontainer.h>
55 #include <comphelper/mimeconfighelper.hxx>
58 #include <targetstatecontrol.hxx>
60 #include <olecomponent.hxx>
62 #include "ownview.hxx"
64 using namespace ::com::sun::star;
66 #ifdef WNT
67 //----------------------------------------------
68 void OleEmbeddedObject::SwitchComponentToRunningState_Impl()
70 if ( m_pOleComponent )
72 try
74 m_pOleComponent->RunObject();
76 catch( embed::UnreachableStateException& )
78 GetRidOfComponent();
79 throw;
81 catch( embed::WrongStateException& )
83 GetRidOfComponent();
84 throw;
87 else
89 throw embed::UnreachableStateException();
93 //----------------------------------------------
94 uno::Sequence< sal_Int32 > OleEmbeddedObject::GetReachableStatesList_Impl(
95 const uno::Sequence< embed::VerbDescriptor >& aVerbList )
97 uno::Sequence< sal_Int32 > aStates(2);
98 aStates[0] = embed::EmbedStates::LOADED;
99 aStates[1] = embed::EmbedStates::RUNNING;
100 for ( sal_Int32 nInd = 0; nInd < aVerbList.getLength(); nInd++ )
101 if ( aVerbList[nInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_OPEN )
103 aStates.realloc(3);
104 aStates[2] = embed::EmbedStates::ACTIVE;
107 return aStates;
110 //----------------------------------------------
111 uno::Sequence< sal_Int32 > OleEmbeddedObject::GetIntermediateVerbsSequence_Impl( sal_Int32 nNewState )
113 OSL_ENSURE( m_nObjectState != embed::EmbedStates::LOADED, "Loaded object is switched to running state without verbs using!" );
115 // actually there will be only one verb
116 if ( m_nObjectState == embed::EmbedStates::RUNNING && nNewState == embed::EmbedStates::ACTIVE )
118 uno::Sequence< sal_Int32 > aVerbs( 1 );
119 aVerbs[0] = embed::EmbedVerbs::MS_OLEVERB_OPEN;
122 return uno::Sequence< sal_Int32 >();
124 #endif
125 //----------------------------------------------
126 void OleEmbeddedObject::MoveListeners()
128 if ( m_pInterfaceContainer )
130 // move state change listeners
132 ::cppu::OInterfaceContainerHelper* pStateChangeContainer =
133 m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< embed::XStateChangeListener >*) NULL ) );
134 if ( pStateChangeContainer != NULL )
136 uno::Reference< embed::XStateChangeBroadcaster > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
137 if ( xWrappedObject.is() )
139 ::cppu::OInterfaceIteratorHelper pIterator( *pStateChangeContainer );
140 while ( pIterator.hasMoreElements() )
144 xWrappedObject->addStateChangeListener( (embed::XStateChangeListener*)pIterator.next() );
146 catch( uno::RuntimeException& )
148 pIterator.remove();
155 // move event listeners
157 ::cppu::OInterfaceContainerHelper* pEventContainer =
158 m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< document::XEventListener >*) NULL ) );
159 if ( pEventContainer != NULL )
161 uno::Reference< document::XEventBroadcaster > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
162 if ( xWrappedObject.is() )
164 ::cppu::OInterfaceIteratorHelper pIterator( *pEventContainer );
165 while ( pIterator.hasMoreElements() )
169 xWrappedObject->addEventListener( (document::XEventListener*)pIterator.next() );
171 catch( uno::RuntimeException& )
173 pIterator.remove();
180 // move close listeners
182 ::cppu::OInterfaceContainerHelper* pCloseContainer =
183 m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
184 if ( pCloseContainer != NULL )
186 uno::Reference< util::XCloseBroadcaster > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY );
187 if ( xWrappedObject.is() )
189 ::cppu::OInterfaceIteratorHelper pIterator( *pCloseContainer );
190 while ( pIterator.hasMoreElements() )
194 xWrappedObject->addCloseListener( (util::XCloseListener*)pIterator.next() );
196 catch( uno::RuntimeException& )
198 pIterator.remove();
205 delete m_pInterfaceContainer;
206 m_pInterfaceContainer = NULL;
210 //----------------------------------------------
211 uno::Reference< embed::XStorage > OleEmbeddedObject::CreateTemporarySubstorage( ::rtl::OUString& o_aStorageName )
213 uno::Reference< embed::XStorage > xResult;
215 for ( sal_Int32 nInd = 0; nInd < 32000 && !xResult.is(); nInd++ )
217 ::rtl::OUString aName = ::rtl::OUString::valueOf( nInd );
218 aName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TMPSTOR" ) );
219 aName += m_aEntryName;
220 if ( !m_xParentStorage->hasByName( aName ) )
222 xResult = m_xParentStorage->openStorageElement( aName, embed::ElementModes::READWRITE );
223 o_aStorageName = aName;
227 if ( !xResult.is() )
229 o_aStorageName = ::rtl::OUString();
230 throw uno::RuntimeException();
233 return xResult;
236 //----------------------------------------------
237 ::rtl::OUString OleEmbeddedObject::MoveToTemporarySubstream()
239 ::rtl::OUString aResult;
240 for ( sal_Int32 nInd = 0; nInd < 32000 && !aResult.getLength(); nInd++ )
242 ::rtl::OUString aName = ::rtl::OUString::valueOf( nInd );
243 aName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TMPSTREAM" ) );
244 aName += m_aEntryName;
245 if ( !m_xParentStorage->hasByName( aName ) )
247 m_xParentStorage->renameElement( m_aEntryName, aName );
248 aResult = aName;
252 if ( !aResult.getLength() )
253 throw uno::RuntimeException();
255 return aResult;
258 //----------------------------------------------
259 sal_Bool OleEmbeddedObject::TryToConvertToOOo()
261 sal_Bool bResult = sal_False;
263 ::rtl::OUString aStorageName;
264 ::rtl::OUString aTmpStreamName;
265 sal_Int32 nStep = 0;
267 if ( m_pOleComponent || m_bReadOnly )
268 return sal_False;
272 changeState( embed::EmbedStates::LOADED );
274 // the stream must be seekable
275 uno::Reference< io::XSeekable > xSeekable( m_xObjectStream, uno::UNO_QUERY_THROW );
276 xSeekable->seek( 0 );
277 ::rtl::OUString aFilterName = OwnView_Impl::GetFilterNameFromExtentionAndInStream( m_xFactory, ::rtl::OUString(), m_xObjectStream->getInputStream() );
279 // use the solution only for OOXML format currently
280 if ( aFilterName.getLength()
281 && ( aFilterName.equals( ::rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM( "Calc MS Excel 2007 XML" ) ) )
282 || aFilterName.equals( ::rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM( "Impress MS PowerPoint 2007 XML" ) ) )
283 || aFilterName.equals( ::rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM( "MS Word 2007 XML" ) ) ) ) )
285 uno::Reference< container::XNameAccess > xFilterFactory(
286 m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
287 uno::UNO_QUERY_THROW );
289 ::rtl::OUString aDocServiceName;
290 uno::Any aFilterAnyData = xFilterFactory->getByName( aFilterName );
291 uno::Sequence< beans::PropertyValue > aFilterData;
292 if ( aFilterAnyData >>= aFilterData )
294 for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
295 if ( aFilterData[nInd].Name.equalsAscii( "DocumentService" ) )
296 aFilterData[nInd].Value >>= aDocServiceName;
299 if ( aDocServiceName.getLength() )
301 // create the model
302 uno::Sequence< uno::Any > aArguments(1);
303 aArguments[0] <<= beans::NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EmbeddedObject" ) ), uno::makeAny( (sal_Bool)sal_True ));
305 uno::Reference< util::XCloseable > xDocument( m_xFactory->createInstanceWithArguments( aDocServiceName, aArguments ), uno::UNO_QUERY_THROW );
306 uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY_THROW );
307 uno::Reference< document::XStorageBasedDocument > xStorDoc( xDocument, uno::UNO_QUERY_THROW );
309 // let the model behave as embedded one
310 uno::Reference< frame::XModel > xModel( xDocument, uno::UNO_QUERY_THROW );
311 uno::Sequence< beans::PropertyValue > aSeq( 1 );
312 aSeq[0].Name = ::rtl::OUString::createFromAscii( "SetEmbedded" );
313 aSeq[0].Value <<= sal_True;
314 xModel->attachResource( ::rtl::OUString(), aSeq );
316 // load the model from the stream
317 uno::Sequence< beans::PropertyValue > aArgs( 5 );
318 aArgs[0].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" );
319 aArgs[0].Value <<= m_aEntryName;
320 aArgs[1].Name = ::rtl::OUString::createFromAscii( "ReadOnly" );
321 aArgs[1].Value <<= sal_True;
322 aArgs[2].Name = ::rtl::OUString::createFromAscii( "FilterName" );
323 aArgs[2].Value <<= aFilterName;
324 aArgs[3].Name = ::rtl::OUString::createFromAscii( "URL" );
325 aArgs[3].Value <<= ::rtl::OUString::createFromAscii( "private:stream" );
326 aArgs[4].Name = ::rtl::OUString::createFromAscii( "InputStream" );
327 aArgs[4].Value <<= m_xObjectStream->getInputStream();
329 xSeekable->seek( 0 );
330 xLoadable->load( aArgs );
332 // the model is successfuly loaded, create a new storage and store the model to the storage
333 uno::Reference< embed::XStorage > xTmpStorage = CreateTemporarySubstorage( aStorageName );
334 xStorDoc->storeToStorage( xTmpStorage, uno::Sequence< beans::PropertyValue >() );
335 xDocument->close( sal_True );
336 uno::Reference< beans::XPropertySet > xStorProps( xTmpStorage, uno::UNO_QUERY_THROW );
337 ::rtl::OUString aMediaType;
338 xStorProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType;
339 xTmpStorage->dispose();
341 // look for the related embedded object factory
342 ::comphelper::MimeConfigurationHelper aConfigHelper( m_xFactory );
343 ::rtl::OUString aEmbedFactory;
344 if ( aMediaType.getLength() )
345 aEmbedFactory = aConfigHelper.GetFactoryNameByMediaType( aMediaType );
347 if ( !aEmbedFactory.getLength() )
348 throw uno::RuntimeException();
350 uno::Reference< uno::XInterface > xFact = m_xFactory->createInstance( aEmbedFactory );
352 uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY_THROW );
354 // now the object should be adjusted to become the wrapper
355 nStep = 1;
356 uno::Reference< lang::XComponent > xComp( m_xObjectStream, uno::UNO_QUERY_THROW );
357 xComp->dispose();
358 m_xObjectStream = uno::Reference< io::XStream >();
359 m_nObjectState = -1;
361 nStep = 2;
362 aTmpStreamName = MoveToTemporarySubstream();
364 nStep = 3;
365 m_xParentStorage->renameElement( aStorageName, m_aEntryName );
367 nStep = 4;
368 m_xWrappedObject.set( xEmbCreator->createInstanceInitFromEntry( m_xParentStorage, m_aEntryName, uno::Sequence< beans::PropertyValue >(), uno::Sequence< beans::PropertyValue >() ), uno::UNO_QUERY_THROW );
370 bResult = sal_True; // the change is no more revertable
373 m_xParentStorage->removeElement( aTmpStreamName );
375 catch( uno::Exception& )
377 // the success of the removing is not so important
382 catch( uno::Exception& )
384 // repair the object if necessary
385 switch( nStep )
387 case 4:
388 case 3:
389 if ( aTmpStreamName.getLength() && aTmpStreamName != m_aEntryName )
392 if ( m_xParentStorage->hasByName( m_aEntryName ) )
393 m_xParentStorage->removeElement( m_aEntryName );
394 m_xParentStorage->renameElement( aTmpStreamName, m_aEntryName );
396 catch ( uno::Exception& )
398 try {
399 close( sal_True );
400 } catch( uno::Exception& ) {}
402 m_xParentStorage->dispose(); // ??? the storage has information loss, it should be closed without commiting!
403 throw uno::RuntimeException(); // the repairing is not possible
405 case 2:
408 m_xObjectStream = m_xParentStorage->openStreamElement( m_aEntryName, m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE );
409 m_nObjectState = embed::EmbedStates::LOADED;
411 catch( uno::Exception& )
413 try {
414 close( sal_True );
415 } catch( uno::Exception& ) {}
417 throw uno::RuntimeException(); // the repairing is not possible
419 // no break as designed!
421 case 1:
422 case 0:
423 if ( aStorageName.getLength() )
424 try {
425 m_xParentStorage->removeElement( aStorageName );
426 } catch( uno::Exception& ) { OSL_ASSERT( "Can not remove temporary storage!" ); }
427 break;
431 if ( bResult )
433 // the conversion was done successfuly, now the additional initializations should happen
435 MoveListeners();
436 m_xWrappedObject->setClientSite( m_xClientSite );
437 if ( m_xParent.is() )
439 uno::Reference< container::XChild > xChild( m_xWrappedObject, uno::UNO_QUERY );
440 if ( xChild.is() )
441 xChild->setParent( m_xParent );
446 return bResult;
449 //----------------------------------------------
450 void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState )
451 throw ( embed::UnreachableStateException,
452 embed::WrongStateException,
453 uno::Exception,
454 uno::RuntimeException )
456 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::changeState" );
458 // begin wrapping related part ====================
459 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
460 if ( xWrappedObject.is() )
462 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
463 xWrappedObject->changeState( nNewState );
464 return;
466 // end wrapping related part ====================
468 ::osl::ResettableMutexGuard aGuard( m_aMutex );
470 if ( m_bDisposed )
471 throw lang::DisposedException(); // TODO
473 if ( m_nObjectState == -1 )
474 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
475 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
477 // in case the object is already in requested state
478 if ( m_nObjectState == nNewState )
479 return;
481 #ifdef WNT
482 if ( m_pOleComponent )
484 if ( m_nTargetState != -1 )
486 // means that the object is currently trying to reach the target state
487 throw embed::StateChangeInProgressException( ::rtl::OUString(),
488 uno::Reference< uno::XInterface >(),
489 m_nTargetState );
492 TargetStateControl_Impl aControl( m_nTargetState, nNewState );
494 // TODO: additional verbs can be a problem, since nobody knows how the object
495 // will behave after activation
497 sal_Int32 nOldState = m_nObjectState;
498 aGuard.clear();
499 StateChangeNotification_Impl( sal_True, nOldState, nNewState );
500 aGuard.reset();
504 if ( nNewState == embed::EmbedStates::LOADED )
506 // This means just closing of the current object
507 // If component can not be closed the object stays in loaded state
508 // and it holds reference to "incomplete" component
509 // If the object is switched to running state later
510 // the component will become "complete"
512 // the loaded state must be set before, because of notifications!
513 m_nObjectState = nNewState;
516 VerbExecutionControllerGuard aVerbGuard( m_aVerbExecutionController );
517 m_pOleComponent->CloseObject();
520 // GetRidOfComponent();
521 aGuard.clear();
522 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
523 aGuard.reset();
525 else if ( nNewState == embed::EmbedStates::RUNNING || nNewState == embed::EmbedStates::ACTIVE )
527 if ( m_nObjectState == embed::EmbedStates::LOADED )
529 // if the target object is in loaded state and a different state is specified
530 // as a new one the object first must be switched to running state.
532 // the component can exist already in nonrunning state
533 // it can be created during loading to detect type of object
534 CreateOleComponentAndLoad_Impl( m_pOleComponent );
536 SwitchComponentToRunningState_Impl();
537 m_nObjectState = embed::EmbedStates::RUNNING;
538 aGuard.clear();
539 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
540 aGuard.reset();
542 if ( m_pOleComponent && m_bHasSizeToSet )
544 aGuard.clear();
545 try {
546 m_pOleComponent->SetExtent( m_aSizeToSet, m_nAspectToSet );
547 m_bHasSizeToSet = sal_False;
549 catch( uno::Exception& ) {}
550 aGuard.reset();
553 if ( m_nObjectState == nNewState )
554 return;
557 // so now the object is either switched from Active to Running state or vise versa
558 // the notification about object state change will be done asynchronously
559 if ( m_nObjectState == embed::EmbedStates::RUNNING && nNewState == embed::EmbedStates::ACTIVE )
561 // execute OPEN verb, if object does not reach active state it is an object's problem
562 aGuard.clear();
563 m_pOleComponent->ExecuteVerb( embed::EmbedVerbs::MS_OLEVERB_OPEN );
564 aGuard.reset();
566 // some objects do not allow to set the size even in running state
567 if ( m_pOleComponent && m_bHasSizeToSet )
569 aGuard.clear();
570 try {
571 m_pOleComponent->SetExtent( m_aSizeToSet, m_nAspectToSet );
572 m_bHasSizeToSet = sal_False;
574 catch( uno::Exception& ) {}
575 aGuard.reset();
578 m_nObjectState = nNewState;
580 else if ( m_nObjectState == embed::EmbedStates::ACTIVE && nNewState == embed::EmbedStates::RUNNING )
582 aGuard.clear();
583 m_pOleComponent->CloseObject();
584 m_pOleComponent->RunObject(); // Should not fail, the object already was active
585 aGuard.reset();
586 m_nObjectState = nNewState;
588 else
590 throw embed::UnreachableStateException();
593 else
594 throw embed::UnreachableStateException();
596 catch( uno::Exception& )
598 aGuard.clear();
599 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
600 throw;
603 else
604 #endif
606 throw embed::UnreachableStateException();
610 //----------------------------------------------
611 uno::Sequence< sal_Int32 > SAL_CALL OleEmbeddedObject::getReachableStates()
612 throw ( embed::WrongStateException,
613 uno::RuntimeException )
615 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::getReachableStates" );
617 // begin wrapping related part ====================
618 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
619 if ( xWrappedObject.is() )
621 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
622 return xWrappedObject->getReachableStates();
624 // end wrapping related part ====================
626 ::osl::MutexGuard aGuard( m_aMutex );
627 if ( m_bDisposed )
628 throw lang::DisposedException(); // TODO
630 if ( m_nObjectState == -1 )
631 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
632 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
634 #ifdef WNT
635 if ( m_pOleComponent )
637 if ( m_nObjectState == embed::EmbedStates::LOADED )
639 // the list of supported verbs can be retrieved only when object is in running state
640 throw embed::NeedsRunningStateException(); // TODO:
643 // the list of states can only be guessed based on standard verbs,
644 // since there is no way to detect what additional verbs do
645 return GetReachableStatesList_Impl( m_pOleComponent->GetVerbList() );
647 else
648 #endif
650 return uno::Sequence< sal_Int32 >();
654 //----------------------------------------------
655 sal_Int32 SAL_CALL OleEmbeddedObject::getCurrentState()
656 throw ( embed::WrongStateException,
657 uno::RuntimeException )
659 // begin wrapping related part ====================
660 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
661 if ( xWrappedObject.is() )
663 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
664 return xWrappedObject->getCurrentState();
666 // end wrapping related part ====================
668 ::osl::MutexGuard aGuard( m_aMutex );
669 if ( m_bDisposed )
670 throw lang::DisposedException(); // TODO
672 if ( m_nObjectState == -1 )
673 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
674 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
676 // TODO: Shouldn't we ask object? ( I guess no )
677 return m_nObjectState;
680 //----------------------------------------------
681 void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID )
682 throw ( lang::IllegalArgumentException,
683 embed::WrongStateException,
684 embed::UnreachableStateException,
685 uno::Exception,
686 uno::RuntimeException )
688 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::doVerb" );
690 // begin wrapping related part ====================
691 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
692 if ( xWrappedObject.is() )
694 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
695 xWrappedObject->doVerb( nVerbID );
696 return;
698 // end wrapping related part ====================
700 ::osl::ResettableMutexGuard aGuard( m_aMutex );
701 if ( m_bDisposed )
702 throw lang::DisposedException(); // TODO
704 if ( m_nObjectState == -1 )
705 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
706 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
708 #ifdef WNT
709 if ( m_pOleComponent )
711 sal_Int32 nOldState = m_nObjectState;
713 // TODO/LATER detect target state here and do a notification
714 // StateChangeNotification_Impl( sal_True, nOldState, nNewState );
715 if ( m_nObjectState == embed::EmbedStates::LOADED )
717 // if the target object is in loaded state
718 // it must be switched to running state to execute verb
719 aGuard.clear();
720 changeState( embed::EmbedStates::RUNNING );
721 aGuard.reset();
724 try {
725 if ( !m_pOleComponent )
726 throw uno::RuntimeException();
728 // ==== the STAMPIT related solution =============================
729 m_aVerbExecutionController.StartControlExecution();
730 // ===============================================================
732 m_pOleComponent->ExecuteVerb( nVerbID );
734 // ==== the STAMPIT related solution =============================
735 sal_Bool bModifiedOnExecution = m_aVerbExecutionController.EndControlExecution_WasModified();
737 // this workaround is implemented for STAMPIT object
738 // if object was modified during verb execution it is saved here
739 if ( bModifiedOnExecution && m_pOleComponent->IsDirty() )
740 SaveObject_Impl();
741 // ===============================================================
743 catch( uno::Exception& )
745 // ==== the STAMPIT related solution =============================
746 m_aVerbExecutionController.EndControlExecution_WasModified();
747 // ===============================================================
749 aGuard.clear();
750 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
751 throw;
754 // the following notification will be done asynchronously
755 // StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
757 else
758 #endif
760 if ( nVerbID == -9 )
762 // the workaround verb to show the object in case no server is available
764 // if it is possible, the object will be converted to OOo format
765 if ( !m_bTriedConversion )
767 m_bTriedConversion = sal_True;
768 if ( TryToConvertToOOo() )
770 changeState( embed::EmbedStates::UI_ACTIVE );
771 return;
775 if ( !m_pOwnView && m_xObjectStream.is() )
777 try {
778 uno::Reference< io::XSeekable > xSeekable( m_xObjectStream, uno::UNO_QUERY );
779 if ( xSeekable.is() )
780 xSeekable->seek( 0 );
782 m_pOwnView = new OwnView_Impl( m_xFactory, m_xObjectStream->getInputStream() );
783 m_pOwnView->acquire();
785 catch( uno::RuntimeException& )
787 throw;
789 catch( uno::Exception& )
794 if ( !m_pOwnView || !m_pOwnView->Open() )
795 throw embed::UnreachableStateException();
797 else
798 throw embed::UnreachableStateException();
802 //----------------------------------------------
803 uno::Sequence< embed::VerbDescriptor > SAL_CALL OleEmbeddedObject::getSupportedVerbs()
804 throw ( embed::WrongStateException,
805 uno::RuntimeException )
807 RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObject::getSupportedVerb" );
809 // begin wrapping related part ====================
810 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
811 if ( xWrappedObject.is() )
813 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
814 return xWrappedObject->getSupportedVerbs();
816 // end wrapping related part ====================
818 ::osl::MutexGuard aGuard( m_aMutex );
819 if ( m_bDisposed )
820 throw lang::DisposedException(); // TODO
822 if ( m_nObjectState == -1 )
823 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
824 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
825 #ifdef WNT
826 if ( m_pOleComponent )
828 // registry could be used in this case
829 // if ( m_nObjectState == embed::EmbedStates::LOADED )
830 // {
831 // // the list of supported verbs can be retrieved only when object is in running state
832 // throw embed::NeedsRunningStateException(); // TODO:
833 // }
835 return m_pOleComponent->GetVerbList();
837 else
838 #endif
840 return uno::Sequence< embed::VerbDescriptor >();
844 //----------------------------------------------
845 void SAL_CALL OleEmbeddedObject::setClientSite(
846 const uno::Reference< embed::XEmbeddedClient >& xClient )
847 throw ( embed::WrongStateException,
848 uno::RuntimeException )
850 // begin wrapping related part ====================
851 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
852 if ( xWrappedObject.is() )
854 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
855 xWrappedObject->setClientSite( xClient );
856 return;
858 // end wrapping related part ====================
860 ::osl::MutexGuard aGuard( m_aMutex );
861 if ( m_bDisposed )
862 throw lang::DisposedException(); // TODO
864 if ( m_xClientSite != xClient)
866 if ( m_nObjectState != embed::EmbedStates::LOADED && m_nObjectState != embed::EmbedStates::RUNNING )
867 throw embed::WrongStateException(
868 ::rtl::OUString::createFromAscii( "The client site can not be set currently!\n" ),
869 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
871 m_xClientSite = xClient;
875 //----------------------------------------------
876 uno::Reference< embed::XEmbeddedClient > SAL_CALL OleEmbeddedObject::getClientSite()
877 throw ( embed::WrongStateException,
878 uno::RuntimeException )
880 // begin wrapping related part ====================
881 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
882 if ( xWrappedObject.is() )
884 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
885 return xWrappedObject->getClientSite();
887 // end wrapping related part ====================
889 ::osl::MutexGuard aGuard( m_aMutex );
890 if ( m_bDisposed )
891 throw lang::DisposedException(); // TODO
893 if ( m_nObjectState == -1 )
894 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
895 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
897 return m_xClientSite;
900 //----------------------------------------------
901 void SAL_CALL OleEmbeddedObject::update()
902 throw ( embed::WrongStateException,
903 uno::Exception,
904 uno::RuntimeException )
906 // begin wrapping related part ====================
907 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
908 if ( xWrappedObject.is() )
910 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
911 xWrappedObject->update();
912 return;
914 // end wrapping related part ====================
916 ::osl::MutexGuard aGuard( m_aMutex );
917 if ( m_bDisposed )
918 throw lang::DisposedException(); // TODO
920 if ( m_nObjectState == -1 )
921 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
922 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
924 if ( m_nUpdateMode == embed::EmbedUpdateModes::EXPLICIT_UPDATE )
926 // TODO: update view representation
928 else
930 // the object must be up to date
931 OSL_ENSURE( m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE, "Unknown update mode!\n" );
935 //----------------------------------------------
936 void SAL_CALL OleEmbeddedObject::setUpdateMode( sal_Int32 nMode )
937 throw ( embed::WrongStateException,
938 uno::RuntimeException )
940 // begin wrapping related part ====================
941 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
942 if ( xWrappedObject.is() )
944 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
945 xWrappedObject->setUpdateMode( nMode );
946 return;
948 // end wrapping related part ====================
950 ::osl::MutexGuard aGuard( m_aMutex );
951 if ( m_bDisposed )
952 throw lang::DisposedException(); // TODO
954 if ( m_nObjectState == -1 )
955 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object has no persistence!\n" ),
956 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
958 OSL_ENSURE( nMode == embed::EmbedUpdateModes::ALWAYS_UPDATE
959 || nMode == embed::EmbedUpdateModes::EXPLICIT_UPDATE,
960 "Unknown update mode!\n" );
961 m_nUpdateMode = nMode;
964 //----------------------------------------------
965 sal_Int64 SAL_CALL OleEmbeddedObject::getStatus( sal_Int64
966 nAspect
968 throw ( embed::WrongStateException,
969 uno::RuntimeException )
971 // begin wrapping related part ====================
972 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
973 if ( xWrappedObject.is() )
975 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
976 return xWrappedObject->getStatus( nAspect );
978 // end wrapping related part ====================
980 ::osl::MutexGuard aGuard( m_aMutex );
981 if ( m_bDisposed )
982 throw lang::DisposedException(); // TODO
984 if ( m_nObjectState == -1 )
985 throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object must be in running state!\n" ),
986 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
988 sal_Int64 nResult = 0;
990 #ifdef WNT
991 if ( m_bGotStatus && m_nStatusAspect == nAspect )
992 nResult = m_nStatus;
993 else if ( m_pOleComponent )
995 // OLE should allow to get status even in loaded state
996 // if ( m_nObjectState == embed::EmbedStates::LOADED )
997 // changeState( m_nObjectState == embed::EmbedStates::RUNNING );
999 m_nStatus = m_pOleComponent->GetMiscStatus( nAspect );
1000 m_nStatusAspect = nAspect;
1001 m_bGotStatus = sal_True;
1002 nResult = m_nStatus;
1004 #endif
1006 // this implementation needs size to be provided after object loading/creating to work in optimal way
1007 return ( nResult | embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD );
1010 //----------------------------------------------
1011 void SAL_CALL OleEmbeddedObject::setContainerName( const ::rtl::OUString& sName )
1012 throw ( uno::RuntimeException )
1014 // begin wrapping related part ====================
1015 uno::Reference< embed::XEmbeddedObject > xWrappedObject = m_xWrappedObject;
1016 if ( xWrappedObject.is() )
1018 // the object was converted to OOo embedded object, the current implementation is now only a wrapper
1019 xWrappedObject->setContainerName( sName );
1020 return;
1022 // end wrapping related part ====================
1024 ::osl::MutexGuard aGuard( m_aMutex );
1025 if ( m_bDisposed )
1026 throw lang::DisposedException(); // TODO
1028 m_aContainerName = sName;