/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// the class is used to detect STAMPIT object, that can never be active if ( !m_bVerbExecutionInProgress && !m_bWasEverActive )
{
m_bVerbExecutionInProgress = true;
m_nVerbExecutionThreadIdentifier = osl::Thread::getCurrentIdentifier();
m_bChangedOnVerbExecution = false;
}
}
uno::Reference< io::XStream > OleEmbeddedObject::TryToGetAcceptableFormat_Impl( const uno::Reference< io::XStream >& xStream )
{ // TODO/LATER: Actually this should be done by a centralized component ( may be a graphical filter ) if ( !m_xContext.is() ) throw uno::RuntimeException();
// the OlePres stream must have additional header // TODO/LATER: might need to be extended in future (actually makes sense only for SO7 format)
uno::Reference< io::XInputStream > xInCacheStream = xCachedVisualRepresentation->getInputStream(); if ( !xInCacheStream.is() ) throw uno::RuntimeException();
// write 0xFFFFFFFF at the beginning
uno::Sequence< sal_Int8 > aData( 4 ); auto pData = aData.getArray();
* reinterpret_cast<sal_uInt32*>(pData) = 0xFFFFFFFF;
OSL_ENSURE( !m_pOleComponent || !m_aTempURL.isEmpty(), "The temporary file must exist if there is a component!" ); if ( !m_aTempURL.isEmpty() )
{ try
{ // open temporary file for reading
uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(
ucb::SimpleFileAccess::create( m_xContext ) );
if ( nInd == 0 )
{ // to be compatible with the old versions Ole10Native is checked after OlePress000
aStreamName = "\001Ole10Native"; try
{ if ( ( xNameContainer->getByName( aStreamName ) >>= xCachedCopyStream ) && xCachedCopyStream.is() )
{
xResult = TryToGetAcceptableFormat_Impl( xCachedCopyStream ); if ( xResult.is() ) break;
}
} catch( const uno::Exception& )
{}
}
}
try
{ if ( bAllowToRepair50 && !xResult.is() )
{
OUString aOrigContName( u"Ole-Object"_ustr ); if ( xNameContainer->hasByName( aOrigContName ) )
{
uno::Reference< embed::XClassifiedObject > xClassified( xNameContainer, uno::UNO_QUERY_THROW ); if ( MimeConfigurationHelper::ClassIDsEqual( xClassified->getClassID(), MimeConfigurationHelper::GetSequenceClassID( SO3_OUT_CLASSID ) ) )
{ // this is an OLE object wrongly stored in 5.0 format // this object must be repaired since SO7 has done it
uno::Reference< io::XInputStream > xOrigInputStream; if ( ( xNameContainer->getByName( aOrigContName ) >>= xOrigInputStream )
&& xOrigInputStream.is() )
{ // the provided input stream must be based on temporary medium and must be independent // from the stream the storage is based on
uno::Reference< io::XSeekable > xOrigSeekable( xOrigInputStream, uno::UNO_QUERY ); if ( xOrigSeekable.is() )
xOrigSeekable->seek( 0 );
uno::Reference< lang::XComponent > xNameContDisp( xNameContainer, uno::UNO_QUERY_THROW );
xNameContDisp->dispose(); // free the original stream
if ( xStream == m_xObjectStream )
{ if ( !m_aTempURL.isEmpty() )
{ // this is the own stream, so the temporary URL must be cleaned if it exists
KillFile_Impl( m_aTempURL, m_xContext );
m_aTempURL.clear();
}
#ifdef _WIN32 // retry to create the component after recovering
GetRidOfComponent(&rGuard);
try
{
CreateOleComponentAndLoad_Impl();
m_aClassID = m_pOleComponent->GetCLSID(); // was not set during construction
} catch( const uno::Exception& )
{
GetRidOfComponent(&rGuard);
} #endif
}
SAL_WARN_IF( m_nObjectState == -1, "embeddedobj.ole", "The object has no persistence!" );
SAL_WARN_IF( m_nObjectState == embed::EmbedStates::LOADED, "embeddedobj.ole", "The object get OnShowWindow in loaded state!" ); if ( m_nObjectState == -1 || m_nObjectState == embed::EmbedStates::LOADED ) returnfalse;
// the object is either activated or deactivated
sal_Int32 nOldState = m_nObjectState; if ( bShow && m_nObjectState == embed::EmbedStates::RUNNING )
{
m_nObjectState = embed::EmbedStates::ACTIVE;
m_aVerbExecutionController.ObjectIsActive();
void OleEmbeddedObject::OnIconChanged_Impl()
{ // TODO/LATER: currently this notification seems to be impossible // MakeEventListenerNotification_Impl( OUString( "OnIconChanged" ) );
}
// For performance reasons the notification currently is ignored, STAMPIT object is the exception, // it can never be active and never call SaveObject, so it is the only way to detect that it is changed
// ==== the STAMPIT related solution ============================= // the following variable is used to detect whether the object was modified during verb execution
m_aVerbExecutionController.ModificationNotificationIsDone();
// The following things are controlled by VerbExecutionController: // - if the verb execution is in progress and the view is changed the object will be stored // after the execution, so there is no need to send the notification. // - the STAMPIT object can never be active. if (m_aVerbExecutionController.CanDoNotification() &&
m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE &&
(MimeConfigurationHelper::ClassIDsEqual(m_aClassID, MimeConfigurationHelper::GetSequenceClassID(0x852ee1c9, 0x9058, 0x44ba, 0x8c, 0x6c, 0x0c, 0x5f, 0xc6, 0x6b, 0xdb, 0x8d)) ||
MimeConfigurationHelper::ClassIDsEqual(m_aClassID, MimeConfigurationHelper::GetSequenceClassID(0xcf1b4491, 0xbea3, 0x4c9f, 0xa7, 0x0f, 0x22, 0x1b, 0x1e, 0xca, 0xef, 0x3e)))
)
{ // The view is changed while the object is in running state, save the new object
m_xCachedVisualRepresentation.clear();
SaveObject_Impl();
MakeEventListenerNotification_Impl( "OnVisAreaChanged", aGuard );
}
// if there is no temporary file, it will be created from the own entry
uno::Reference< embed::XOptimizedStorage > xOptParStorage( m_xParentStorage, uno::UNO_QUERY ); if ( xOptParStorage.is() )
{
m_aTempURL = GetNewFilledTempFile_Impl( xOptParStorage, m_aEntryName, m_xContext );
} elseif ( m_xObjectStream.is() )
{ // load object from the stream
uno::Reference< io::XInputStream > xInStream = m_xObjectStream->getInputStream(); if ( !xInStream.is() ) throw io::IOException(); // TODO: access denied
void OleEmbeddedObject::StoreObjectToStream(uno::Reference<io::XOutputStream> const& xOutStream,
osl::ResettableMutexGuard& rGuard)
{ // this method should be used only on windows if ( m_pOleComponent )
ExecUnlocked([this] { m_pOleComponent->StoreOwnTmpIfNecessary(); }, rGuard);
// now all the changes should be in temporary location if ( m_aTempURL.isEmpty() ) throw uno::RuntimeException();
// open temporary file for reading
uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(
ucb::SimpleFileAccess::create( m_xContext ) );
uno::Reference< io::XInputStream > xTempInStream = xTempAccess->openFileRead( m_aTempURL );
SAL_WARN_IF( !xTempInStream.is(), "embeddedobj.ole", "The object's temporary file can not be reopened for reading!" );
// TODO: use bStoreVisReplace
if ( !xTempInStream.is() )
{ throw io::IOException(); // TODO:
}
// write all the contents to XOutStream
uno::Reference< io::XTruncate > xTrunc( xOutStream, uno::UNO_QUERY_THROW );
xTrunc->truncate();
// TODO: should the view replacement be in the stream ??? // probably it must be specified on storing
} #endif
void OleEmbeddedObject::StoreToLocation_Impl( const uno::Reference< embed::XStorage >& xStorage, const OUString& sEntName, const uno::Sequence< beans::PropertyValue >& lObjArgs, bool bSaveAs, osl::ResettableMutexGuard& rGuard)
{ #ifndef _WIN32
(void)rGuard; #endif // TODO: use lObjArgs // TODO: exchange StoreVisualReplacement by SO file format version?
if ( m_nObjectState == -1 )
{ // the object is still not loaded throw embed::WrongStateException( u"Can't store object without persistence!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
}
if ( m_bWaitSaveCompleted ) throw embed::WrongStateException(
u"The object waits for saveCompleted() call!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
OSL_ENSURE( m_xParentStorage.is() && m_xObjectStream.is(), "The object has no valid persistence!" );
// ignore visual representation provided from outside if it should not be stored if ( !bStoreVis )
xCachedVisualRepresentation.clear();
if ( bStoreVis && !HasVisReplInStream() && !xCachedVisualRepresentation.is() ) throw io::IOException(); // TODO: there is no cached visual representation and nothing is provided from outside
// if the representation is provided from outside it should be copied to a local stream bool bNeedLocalCache = xCachedVisualRepresentation.is();
uno::Reference< io::XStream > xTargetStream;
bool bStoreLoaded = false; if ( m_nObjectState == embed::EmbedStates::LOADED #ifdef _WIN32 // if the object was NOT modified after storing it can be just copied // as if it was in loaded state
|| (m_pOleComponent && !ExecUnlocked([p = m_pOleComponent] { return p->IsDirty(); }, rGuard)) #endif
)
{ bool bOptimizedCopyingDone = false;
if ( !bOptimizedCopyingDone )
{ // if optimized copying fails a normal one should be tried
m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
}
// the locally retrieved representation is always preferable // since the object is in loaded state the representation is unchanged if ( m_xCachedVisualRepresentation.is() )
{
xCachedVisualRepresentation = m_xCachedVisualRepresentation;
bNeedLocalCache = false;
}
if ( bSaveAs )
{ // no need to do it on StoreTo since in this case the replacement is in the stream // and there is no need to cache it even if it is thrown away because the object // is not changed by StoreTo action
if ( bStoreVis != bVisReplIsStored )
{ if ( bStoreVis )
{ if ( !xCachedVisualRepresentation.is() )
xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream, rGuard );
SAL_WARN_IF( !xCachedVisualRepresentation.is(), "embeddedobj.ole", "No representation is available!" );
// the following copying will be done in case it is SaveAs anyway // if it is not SaveAs the seekable access is not required currently // TODO/LATER: may be required in future if ( bSaveAs )
{
uno::Reference< io::XSeekable > xCachedSeek( xCachedVisualRepresentation, uno::UNO_QUERY ); if ( !xCachedSeek.is() )
{
xCachedVisualRepresentation
= GetNewFilledTempStream_Impl( xCachedVisualRepresentation->getInputStream() );
bNeedLocalCache = false;
}
}
InsertVisualCache_Impl(xTargetStream, xCachedVisualRepresentation, rGuard);
} else
{ // the removed representation could be cached by this method if ( !xCachedVisualRepresentation.is() )
xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream, rGuard );
if (!m_bStreamReadOnly)
RemoveVisualCache_Impl(xTargetStream);
}
}
if ( xCachedVisualRepresentation.is() )
{ if ( bNeedLocalCache )
m_xNewCachedVisRepl = GetNewFilledTempStream_Impl( xCachedVisualRepresentation->getInputStream() ); else
m_xNewCachedVisRepl = std::move(xCachedVisualRepresentation);
}
// TODO: register listeners for storages above, in case they are disposed // an exception will be thrown on saveCompleted( true )
} else
{
uno::Reference< lang::XComponent > xComp( xTargetStream, uno::UNO_QUERY ); if ( xComp.is() )
{ try {
xComp->dispose();
} catch( const uno::Exception& )
{
}
}
}
}
void SAL_CALL OleEmbeddedObject::setPersistentEntry( const uno::Reference< embed::XStorage >& xStorage, const OUString& sEntName,
sal_Int32 nEntryConnectionMode, const uno::Sequence< beans::PropertyValue >& lArguments, const uno::Sequence< beans::PropertyValue >& lObjArgs )
{ // begin wrapping related part ====================
uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper
xWrappedObject->setPersistentEntry( xStorage, sEntName, nEntryConnectionMode, lArguments, lObjArgs ); return;
} // end wrapping related part ====================
// TODO: use lObjArgs
// the type of the object must be already set // a kind of typedetection should be done in the factory; // the only exception is object initialized from a stream, // the class ID will be detected from the stream
osl::ResettableMutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
if ( !xStorage.is() ) throw lang::IllegalArgumentException( u"No parent storage is provided!"_ustr, static_cast< ::cppu::OWeakObject* >(this),
1 );
if ( sEntName.isEmpty() ) throw lang::IllegalArgumentException( u"Empty element name is provided!"_ustr, static_cast< ::cppu::OWeakObject* >(this),
2 );
// May be LOADED should be forbidden here ??? if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
&& ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) )
{ // if the object is not loaded // it can not get persistent representation without initialization
// if the object is loaded // it can switch persistent representation only without initialization
for ( beans::PropertyValue const & prop : lObjArgs ) if ( prop.Name == "StoreVisualReplacement" )
prop.Value >>= m_bStoreVisRepl;
#ifdef _WIN32 if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT )
{ if ( m_bFromClipboard )
{ // the object should be initialized from clipboard // impossibility to initialize the object means error here
CreateOleComponentFromClipboard_Impl();
m_aClassID = m_pOleComponent->GetCLSID(); // was not set during construction
m_pOleComponent->RunObject();
m_nObjectState = embed::EmbedStates::RUNNING;
} elseif ( bElExists )
{ // load object from the stream // after the loading the object can appear as a link // will be detected by olecomponent try
{
CreateOleComponentAndLoad_Impl();
m_aClassID = m_pOleComponent->GetCLSID(); // was not set during construction
} catch( const uno::Exception& )
{ // TODO/LATER: detect classID of the object if possible // means that the object inprocess server could not be successfully instantiated
GetRidOfComponent(&aGuard);
}
if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
{ // the document just already changed its stream to store to; // the links to OLE documents switch their persistence in the same way // as normal embedded objects
} elseif ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT )
{ // create a new object, that will be stored in specified stream
CreateOleComponent_Impl();
m_pOleComponent->CreateNewEmbeddedObject( m_aClassID );
m_pOleComponent->RunObject();
m_nObjectState = embed::EmbedStates::RUNNING;
} elseif ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
{ // use URL ( may be content or stream later ) from MediaDescriptor to initialize object
OUString aURL; for ( beans::PropertyValue const & prop : lArguments ) if ( prop.Name == "URL" )
prop.Value >>= aURL;
if ( aURL.isEmpty() ) throw lang::IllegalArgumentException( "Empty URL is provided in the media descriptor!", static_cast< ::cppu::OWeakObject* >(this),
4 );
CreateOleComponent_Impl();
// TODO: the m_bIsLink value must be set already if ( !m_bIsLink )
m_pOleComponent->CreateObjectFromFile( aURL ); else
m_pOleComponent->CreateLinkFromFile( aURL );
m_pOleComponent->RunObject();
m_aClassID = m_pOleComponent->GetCLSID(); // was not set during construction
m_nObjectState = embed::EmbedStates::RUNNING;
} //else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT ) //{ //TODO: //} else throw lang::IllegalArgumentException( "Wrong connection mode is provided!", static_cast< ::cppu::OWeakObject* >(this),
3 );
} #else // On Unix the OLE object can not do anything except storing itself somewhere if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT && bElExists )
{ // TODO/LATER: detect classID of the object // can be a real problem for the links
m_nObjectState = embed::EmbedStates::LOADED;
} elseif ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
{ // do nothing, the object has already switched it's persistence
} else throw lang::IllegalArgumentException( u"Wrong connection mode is provided!"_ustr, static_cast< ::cppu::OWeakObject* >(this),
3 );
#endif
}
void SAL_CALL OleEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage, const OUString& sEntName, const uno::Sequence< beans::PropertyValue >& lArguments, const uno::Sequence< beans::PropertyValue >& lObjArgs )
{ // begin wrapping related part ====================
uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper
xWrappedObject->storeToEntry( xStorage, sEntName, lArguments, lObjArgs ); return;
} // end wrapping related part ====================
::osl::ResettableMutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
// TODO: should the listener notification be done?
}
void SAL_CALL OleEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage, const OUString& sEntName, const uno::Sequence< beans::PropertyValue >& lArguments, const uno::Sequence< beans::PropertyValue >& lObjArgs )
{ // begin wrapping related part ====================
uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper
xWrappedObject->storeAsEntry( xStorage, sEntName, lArguments, lObjArgs ); return;
} // end wrapping related part ====================
::osl::ResettableMutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
// TODO: should the listener notification be done here or in saveCompleted?
}
void SAL_CALL OleEmbeddedObject::saveCompleted( sal_Bool bUseNew )
{ // begin wrapping related part ====================
uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper
xWrappedObject->saveCompleted( bUseNew ); return;
} // end wrapping related part ====================
osl::ResettableMutexGuard aGuard(m_aMutex); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
if ( m_nObjectState == -1 )
{ // the object is still not loaded throw embed::WrongStateException( u"Can't store object without persistence!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
}
// it is allowed to call saveCompleted( false ) for nonstored objects if ( !m_bWaitSaveCompleted && !bUseNew ) return;
if ( bUseNew && m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded
&& m_nObjectState != embed::EmbedStates::LOADED )
{ // the object replacement image should be updated, so the cached size as well
m_bHasCachedSize = false; try
{ // the call will cache the size in case of success // probably it might need to be done earlier, while the object is in active state
getVisualAreaSize_impl(embed::Aspects::MSOLE_CONTENT, aGuard);
} catch( const uno::Exception& )
{}
}
if ( bUseNew )
{
MakeEventListenerNotification_Impl( u"OnSaveAsDone"_ustr, aGuard);
// the object can be changed only on windows // the notification should be done only if the object is not in loaded state if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
{
MakeEventListenerNotification_Impl( u"OnVisAreaChanged"_ustr, aGuard);
}
}
}
sal_Bool SAL_CALL OleEmbeddedObject::hasEntry()
{ // begin wrapping related part ====================
uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper return xWrappedObject->hasEntry();
} // end wrapping related part ====================
::osl::MutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
if ( m_bWaitSaveCompleted ) throw embed::WrongStateException(
u"The object waits for saveCompleted() call!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
if ( m_xObjectStream.is() ) returntrue;
returnfalse;
}
OUString SAL_CALL OleEmbeddedObject::getEntryName()
{ // begin wrapping related part ====================
uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper return xWrappedObject->getEntryName();
} // end wrapping related part ====================
::osl::MutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
if ( m_nObjectState == -1 )
{ // the object is still not loaded throw embed::WrongStateException( u"The object persistence is not initialized!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
}
if ( m_bWaitSaveCompleted ) throw embed::WrongStateException(
u"The object waits for saveCompleted() call!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
return m_aEntryName;
}
void SAL_CALL OleEmbeddedObject::storeOwn()
{ // begin wrapping related part ====================
uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper
xWrappedObject->storeOwn(); return;
} // end wrapping related part ====================
// during switching from Activated to Running and from Running to Loaded states the object will // ask container to store the object, the container has to make decision // to do so or not
osl::ResettableMutexGuard aGuard(m_aMutex); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
if ( m_nObjectState == -1 )
{ // the object is still not loaded throw embed::WrongStateException( u"Can't store object without persistence!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
}
if ( m_bWaitSaveCompleted ) throw embed::WrongStateException(
u"The object waits for saveCompleted() call!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
if ( m_bReadOnly ) throw io::IOException(); // TODO: access denied
// TODO: does this work for links too?
StoreObjectToStream(GetStreamForSaving(), aGuard);
// the replacement is changed probably, and it must be in the object stream if ( !m_pOleComponent->IsWorkaroundActive() )
m_xCachedVisualRepresentation.clear();
SetVisReplInStream( true );
} #endif
if ( m_bStoreVisRepl != HasVisReplInStream() )
{ if ( m_bStoreVisRepl )
{ // the m_xCachedVisualRepresentation must be set or it should be already stored if ( m_xCachedVisualRepresentation.is() )
InsertVisualCache_Impl(m_xObjectStream, m_xCachedVisualRepresentation, aGuard); else
{
m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream, aGuard );
SAL_WARN_IF( !m_xCachedVisualRepresentation.is(), "embeddedobj.ole", "No representation is available!" );
}
} else
{ if ( !m_xCachedVisualRepresentation.is() )
m_xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( m_xObjectStream, aGuard );
RemoveVisualCache_Impl( m_xObjectStream );
}
SetVisReplInStream( m_bStoreVisRepl );
}
if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
{ // the object replacement image should be updated, so the cached size as well
m_bHasCachedSize = false; try
{ // the call will cache the size in case of success // probably it might need to be done earlier, while the object is in active state
getVisualAreaSize_impl(embed::Aspects::MSOLE_CONTENT, aGuard);
} catch( const uno::Exception& )
{}
}
// the object can be changed only on Windows // the notification should be done only if the object is not in loaded state if ( m_pOleComponent && m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE && !bStoreLoaded )
MakeEventListenerNotification_Impl( u"OnVisAreaChanged"_ustr, aGuard);
}
sal_Bool SAL_CALL OleEmbeddedObject::isReadonly()
{ // begin wrapping related part ====================
uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper return xWrappedObject->isReadonly();
} // end wrapping related part ====================
::osl::MutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
if ( m_nObjectState == -1 )
{ // the object is still not loaded throw embed::WrongStateException( u"The object persistence is not initialized!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
}
if ( m_bWaitSaveCompleted ) throw embed::WrongStateException(
u"The object waits for saveCompleted() call!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
return m_bReadOnly;
}
void SAL_CALL OleEmbeddedObject::reload( const uno::Sequence< beans::PropertyValue >& lArguments, const uno::Sequence< beans::PropertyValue >& lObjArgs )
{ // begin wrapping related part ====================
uno::Reference< embed::XEmbedPersist > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper
xWrappedObject->reload( lArguments, lObjArgs ); return;
} // end wrapping related part ====================
// TODO: use lObjArgs
::osl::MutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
if ( m_nObjectState == -1 )
{ // the object is still not loaded throw embed::WrongStateException( u"The object persistence is not initialized!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
}
if ( m_bWaitSaveCompleted ) throw embed::WrongStateException(
u"The object waits for saveCompleted() call!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
// TODO: // throw away current document // load new document from current storage // use meaningful part of lArguments
}
void SAL_CALL OleEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage, const OUString& sEntName )
{ // begin wrapping related part ====================
uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper
xWrappedObject->breakLink( xStorage, sEntName ); return;
} // end wrapping related part ====================
osl::ResettableMutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
if ( !xStorage.is() ) throw lang::IllegalArgumentException( u"No parent storage is provided!"_ustr, static_cast< ::cppu::OWeakObject* >(this),
1 );
if ( sEntName.isEmpty() ) throw lang::IllegalArgumentException( u"Empty element name is provided!"_ustr, static_cast< ::cppu::OWeakObject* >(this),
2 );
// TODO: The object must be at least in Running state; if ( !m_bIsLink || m_nObjectState == -1 || !m_pOleComponent )
{ // it must be a linked initialized object throw embed::WrongStateException(
u"The object is not a valid linked object!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
}
if ( m_bReadOnly ) throw io::IOException(); // TODO: Access denied
if ( m_bWaitSaveCompleted ) throw embed::WrongStateException(
u"The object waits for saveCompleted() call!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
#ifdef _WIN32 // TODO: create an object based on the link
// disconnect the old temporary URL
OUString aOldTempURL = m_aTempURL;
m_aTempURL.clear();
if (nTargetState == embed::EmbedStates::RUNNING)
m_pOleComponent->RunObject(); // the object already was in running state, the server must be installed else// nTargetState == embed::EmbedStates::ACTIVE
{
m_pOleComponent->RunObject(); // the object already was in running state, the server must be installed
m_pOleComponent->ExecuteVerb(embed::EmbedVerbs::MS_OLEVERB_OPEN);
}
sal_Bool SAL_CALL OleEmbeddedObject::isLink()
{ // begin wrapping related part ====================
uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper return xWrappedObject->isLink();
} // end wrapping related part ====================
::osl::MutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
return m_bIsLink;
}
OUString SAL_CALL OleEmbeddedObject::getLinkURL()
{ // begin wrapping related part ====================
uno::Reference< embed::XLinkageSupport > xWrappedObject( m_xWrappedObject, uno::UNO_QUERY ); if ( xWrappedObject.is() )
{ // the object was converted to OOo embedded object, the current implementation is now only a wrapper return xWrappedObject->getLinkURL();
} // end wrapping related part ====================
::osl::MutexGuard aGuard( m_aMutex ); if ( m_bDisposed ) throw lang::DisposedException(); // TODO
if ( m_bWaitSaveCompleted ) throw embed::WrongStateException(
u"The object waits for saveCompleted() call!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
if ( !m_bIsLink ) throw embed::WrongStateException(
u"The object is not a link object!"_ustr, static_cast< ::cppu::OWeakObject* >(this) );
// TODO: probably the link URL can be retrieved from OLE
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.