fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / embeddedobj / source / msole / oleembed.cxx
blobca8b73187b29832b43c865fc2d0139881ea6e08a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <oleembobj.hxx>
21 #include <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"
55 #if defined WNT
56 #include <olecomponent.hxx>
57 #endif
59 using namespace ::com::sun::star;
61 #ifdef WNT
63 void OleEmbeddedObject::SwitchComponentToRunningState_Impl()
65 if ( m_pOleComponent )
67 try
69 m_pOleComponent->RunObject();
71 catch( const embed::UnreachableStateException& )
73 GetRidOfComponent();
74 throw;
76 catch( const embed::WrongStateException& )
78 GetRidOfComponent();
79 throw;
82 else
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 )
98 aStates.realloc(3);
99 aStates[2] = embed::EmbedStates::ACTIVE;
102 return aStates;
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 >();
119 #endif
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& )
143 pIterator.remove();
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& )
168 pIterator.remove();
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& )
193 pIterator.remove();
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;
220 if ( !xResult.is() )
222 o_aStorageName.clear();
223 throw uno::RuntimeException();
226 return xResult;
230 OUString OleEmbeddedObject::MoveToTemporarySubstream()
232 OUString aResult;
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 );
239 aResult = aName;
243 if ( aResult.isEmpty() )
244 throw uno::RuntimeException();
246 return aResult;
250 bool OleEmbeddedObject::TryToConvertToOOo()
252 bool bResult = false;
254 OUString aStorageName;
255 OUString aTmpStreamName;
256 sal_Int32 nStep = 0;
258 if ( m_pOleComponent || m_bReadOnly )
259 return false;
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() )
290 // create the model
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 );
326 OUString aMediaType;
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
344 nStep = 1;
345 uno::Reference< lang::XComponent > xComp( m_xObjectStream, uno::UNO_QUERY_THROW );
346 xComp->dispose();
347 m_xObjectStream = uno::Reference< io::XStream >();
348 m_nObjectState = -1;
350 nStep = 2;
351 aTmpStreamName = MoveToTemporarySubstream();
353 nStep = 3;
354 m_xParentStorage->renameElement( aStorageName, m_aEntryName );
356 nStep = 4;
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
374 switch( nStep )
376 case 4:
377 case 3:
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& )
387 try {
388 close( sal_True );
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
394 case 2:
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& )
402 try {
403 close( sal_True );
404 } catch( const uno::Exception& ) {}
406 throw uno::RuntimeException(); // the repairing is not possible
408 // no break as designed!
410 case 1:
411 case 0:
412 if ( !aStorageName.isEmpty() )
413 try {
414 m_xParentStorage->removeElement( aStorageName );
415 } catch( const uno::Exception& ) { SAL_WARN( "embeddedobj.ole", "Can not remove temporary storage!" ); }
416 break;
420 if ( bResult )
422 // the conversion was done successfully, now the additional initializations should happen
424 MoveListeners();
425 m_xWrappedObject->setClientSite( m_xClientSite );
426 if ( m_xParent.is() )
428 uno::Reference< container::XChild > xChild( m_xWrappedObject, uno::UNO_QUERY );
429 if ( xChild.is() )
430 xChild->setParent( m_xParent );
435 return bResult;
439 void SAL_CALL OleEmbeddedObject::changeState( sal_Int32 nNewState )
440 throw ( embed::UnreachableStateException,
441 embed::WrongStateException,
442 uno::Exception,
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 );
451 return;
453 // end wrapping related part ====================
455 ::osl::ResettableMutexGuard aGuard( m_aMutex );
457 if ( m_bDisposed )
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 )
466 return;
468 #ifdef WNT
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 >(),
476 m_nTargetState );
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;
485 aGuard.clear();
486 StateChangeNotification_Impl( sal_True, nOldState, nNewState );
487 aGuard.reset();
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();
507 aGuard.clear();
508 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
509 aGuard.reset();
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;
524 aGuard.clear();
525 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
526 aGuard.reset();
528 if ( m_pOleComponent && m_bHasSizeToSet )
530 aGuard.clear();
531 try {
532 m_pOleComponent->SetExtent( m_aSizeToSet, m_nAspectToSet );
533 m_bHasSizeToSet = sal_False;
535 catch( const uno::Exception& ) {}
536 aGuard.reset();
539 if ( m_nObjectState == nNewState )
540 return;
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
548 aGuard.clear();
549 m_pOleComponent->ExecuteVerb( embed::EmbedVerbs::MS_OLEVERB_OPEN );
550 aGuard.reset();
552 // some objects do not allow to set the size even in running state
553 if ( m_pOleComponent && m_bHasSizeToSet )
555 aGuard.clear();
556 try {
557 m_pOleComponent->SetExtent( m_aSizeToSet, m_nAspectToSet );
558 m_bHasSizeToSet = sal_False;
560 catch( uno::Exception& ) {}
561 aGuard.reset();
564 m_nObjectState = nNewState;
566 else if ( m_nObjectState == embed::EmbedStates::ACTIVE && nNewState == embed::EmbedStates::RUNNING )
568 aGuard.clear();
569 m_pOleComponent->CloseObject();
570 m_pOleComponent->RunObject(); // Should not fail, the object already was active
571 aGuard.reset();
572 m_nObjectState = nNewState;
574 else
576 throw embed::UnreachableStateException();
579 else
580 throw embed::UnreachableStateException();
582 catch( uno::Exception& )
584 aGuard.clear();
585 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
586 throw;
589 else
590 #else
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 );
598 return;
601 #endif
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 );
622 if ( m_bDisposed )
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) );
629 #ifdef WNT
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() );
642 else
643 #endif
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 );
664 if ( m_bDisposed )
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;
675 namespace
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;
682 sal_Int32 nRead;
685 nRead = xIn->readBytes(aData, nChunkSize);
686 nTotalRead += nRead;
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)
698 OUString sUrl;
700 // the solution is only active for Unix systems
701 #ifndef WNT
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&)
722 // ignore
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);
731 if (!bCopied)
732 bCopied = lcl_CopyStream(xObjectStream->getInputStream(), xStream->getOutputStream());
734 if (bCopied)
736 xNativeTempFile->setPropertyValue("RemoveFile",
737 uno::makeAny(sal_False));
738 uno::Any aUrl = xNativeTempFile->getPropertyValue("Uri");
739 aUrl >>= sUrl;
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);
748 else
750 xNativeTempFile->setPropertyValue("RemoveFile",
751 uno::makeAny(sal_True));
753 #else
754 (void) xFactory;
755 (void) xObjectStream;
756 #endif
757 return sUrl;
762 void SAL_CALL OleEmbeddedObject::doVerb( sal_Int32 nVerbID )
763 throw ( lang::IllegalArgumentException,
764 embed::WrongStateException,
765 embed::UnreachableStateException,
766 uno::Exception,
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 );
775 return;
777 // end wrapping related part ====================
779 ::osl::ResettableMutexGuard aGuard( m_aMutex );
780 if ( m_bDisposed )
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) );
787 #ifdef WNT
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
798 aGuard.clear();
799 changeState( embed::EmbedStates::RUNNING );
800 aGuard.reset();
803 try {
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() )
819 SaveObject_Impl();
822 catch( uno::Exception& )
824 // ==== the STAMPIT related solution =============================
825 m_aVerbExecutionController.EndControlExecution_WasModified();
828 aGuard.clear();
829 StateChangeNotification_Impl( sal_False, nOldState, m_nObjectState );
830 throw;
834 else
835 #endif
837 if ( nVerbID == -9 )
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 );
848 return;
852 if ( !m_pOwnView && m_xObjectStream.is() && m_aFilterName != "Text" )
854 try {
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& )
864 throw;
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);
886 else
887 throw embed::UnreachableStateException();
890 else
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 );
913 if ( m_bDisposed )
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) );
919 #ifdef WNT
920 if ( m_pOleComponent )
922 // registry could be used in this case
923 // if ( m_nObjectState == embed::EmbedStates::LOADED )
924 // {
925 // // the list of supported verbs can be retrieved only when object is in running state
926 // throw embed::NeedsRunningStateException(); // TODO:
927 // }
929 return m_pOleComponent->GetVerbList();
931 else
932 #endif
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 );
950 return;
952 // end wrapping related part ====================
954 ::osl::MutexGuard aGuard( m_aMutex );
955 if ( m_bDisposed )
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 );
984 if ( m_bDisposed )
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,
997 uno::Exception,
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();
1006 return;
1008 // end wrapping related part ====================
1010 ::osl::MutexGuard aGuard( m_aMutex );
1011 if ( m_bDisposed )
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
1022 else
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 );
1040 return;
1042 // end wrapping related part ====================
1044 ::osl::MutexGuard aGuard( m_aMutex );
1045 if ( m_bDisposed )
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
1060 nAspect
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 );
1075 if ( m_bDisposed )
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;
1084 #ifdef WNT
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;
1095 #endif
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 );
1111 return;
1113 // end wrapping related part ====================
1115 ::osl::MutexGuard aGuard( m_aMutex );
1116 if ( m_bDisposed )
1117 throw lang::DisposedException(); // TODO
1119 m_aContainerName = sName;
1123 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */