/* -*- 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& )
{}
}
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.