/* -*- 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 .
*/
rtl::Reference<EmbedEventListener_Impl> EmbedEventListener_Impl::Create( EmbeddedObjectRef* p )
{
rtl::Reference<EmbedEventListener_Impl> pRet(new EmbedEventListener_Impl( p ));
if ( p->GetObject().is() )
{
p->GetObject()->addStateChangeListener( pRet );
uno::Reference < util::XCloseable > xClose = p->GetObject();
DBG_ASSERT( xClose.is(), "Object does not support XCloseable!" ); if ( xClose.is() )
xClose->addCloseListener( pRet );
uno::Reference < document::XEventBroadcaster > xBrd = p->GetObject(); if ( xBrd.is() )
xBrd->addEventListener( pRet );
pRet->nState = p->GetObject()->getCurrentState(); if ( pRet->nState == embed::EmbedStates::RUNNING )
{
uno::Reference < util::XModifiable > xMod( p->GetObject()->getComponent(), uno::UNO_QUERY ); if ( xMod.is() ) // listen for changes in running state (update replacements in case of changes)
xMod->addModifyListener( pRet );
}
}
// TODO/LATER: container must be set before! // When is this event created? Who sets the new container when it changed? if ((pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON)
&& nOldState != embed::EmbedStates::LOADED && !pObject->IsChart() && !bProtected) // get new replacement after deactivation
pObject->UpdateReplacement();
if( pObject->IsChart() && nOldState == embed::EmbedStates::UI_ACTIVE )
{ //create a new metafile replacement when leaving the edit mode //for buggy documents where the old image looks different from the correct one if( xMod.is() && !xMod->isModified() )//in case of modification a new replacement will be requested anyhow
pObject->UpdateReplacementOnDemand();
}
if ( xMod.is() && nOldState == embed::EmbedStates::LOADED ) // listen for changes (update replacements in case of changes)
xMod->addModifyListener( this );
} elseif ( nNewState == embed::EmbedStates::LOADED )
{ // in loaded state we can't listen if ( xMod.is() )
xMod->removeModifyListener( this );
}
}
if ( nState == embed::EmbedStates::RUNNING )
{ // updates only necessary in non-active states if( pObject->IsChart() )
pObject->UpdateReplacementOnDemand(); else
pObject->UpdateReplacement();
} elseif ( nState == embed::EmbedStates::ACTIVE ||
nState == embed::EmbedStates::UI_ACTIVE ||
nState == embed::EmbedStates::INPLACE_ACTIVE )
{ // in case the object is inplace or UI active the replacement image should be updated on demand
pObject->UpdateReplacementOnDemand();
}
}
void SAL_CALL EmbedEventListener_Impl::queryClosing( const lang::EventObject& Source, sal_Bool )
{ // An embedded object can be shared between several objects (f.e. for undo purposes) // the object will not be closed before the last "customer" is destroyed // Now the EmbeddedObjectRef helper class works like a "lock" on the object if ( pObject && pObject->IsLocked() && Source.Source == pObject->GetObject() ) throw util::CloseVetoException();
}
// #i104867#
sal_uInt32 mnGraphicVersion;
awt::Size aDefaultSizeForChart_In_100TH_MM;//#i103460# charts do not necessarily have an own size within ODF files, in this case they need to use the size settings from the surrounding frame, which is made available with this member
if ( mpImpl->bIsLocked )
{ try
{
mpImpl->mxObj->changeState(embed::EmbedStates::LOADED);
mpImpl->mxObj->close( true );
} catch (const util::CloseVetoException&)
{ // there's still someone who needs the object!
} catch (const uno::Exception&)
{
TOOLS_WARN_EXCEPTION("svtools.misc", "Error on switching of the object to loaded state and closing");
}
}
}
if (mpImpl->mxListener.is())
{
mpImpl->mxListener->pObject = nullptr;
mpImpl->mxListener.clear();
}
void EmbeddedObjectRef::GetReplacement( bool bUpdate )
{ if ( bUpdate )
{ // Do not clear / reset mpImpl->oGraphic, because it would appear as no replacement // on any call to getReplacementGraphic during the external calls to the OLE object, // which may release mutexes. Only replace it when done.
mpImpl->aMediaType.clear();
} elseif (mpImpl->oGraphic)
{
OSL_FAIL("No update, but replacement exists already!"); return;
}
std::unique_ptr<SvStream> pGraphicStream(GetGraphicStream( bUpdate )); if (!pGraphicStream && bUpdate && (!mpImpl->oGraphic || mpImpl->oGraphic->IsNone()))
{ // We have no old graphic, tried to get an updated one, but that failed. Try to get an old // graphic instead of having no graphic at all.
pGraphicStream = GetGraphicStream(false);
SAL_WARN("svtools.misc", "EmbeddedObjectRef::GetReplacement: failed to get updated graphic stream");
}
const Graphic* EmbeddedObjectRef::GetGraphic() const
{ try
{ if ( mpImpl->bNeedUpdate ) // bNeedUpdate will be set to false while retrieving new replacement const_cast < EmbeddedObjectRef* >(this)->GetReplacement(true); elseif ( !mpImpl->oGraphic ) const_cast < EmbeddedObjectRef* >(this)->GetReplacement(false);
} catch( const uno::Exception& )
{
DBG_UNHANDLED_EXCEPTION("svtools.misc", "Something went wrong on getting the graphic");
}
if (mpImpl->mxObj.is())
{ try
{
aSize = mpImpl->mxObj->getVisualAreaSize(mpImpl->nViewAspect);
} catch(const embed::NoVisualAreaSizeException&)
{
SAL_WARN("svtools.misc", "EmbeddedObjectRef::GetSize: no visual area size");
} catch (const uno::Exception&)
{
TOOLS_WARN_EXCEPTION("svtools.misc", "Something went wrong on getting of the size of the object");
}
try
{
aSourceMapMode = MapMode(VCLUnoHelper::UnoEmbed2VCLMapUnit(mpImpl->mxObj->getMapUnit(mpImpl->nViewAspect)));
} catch (const uno::Exception&)
{
TOOLS_WARN_EXCEPTION("svtools.misc", "Can not get the map mode");
}
}
if (bUpdateAllowed)
{ // update wanted or no stream in container storage available
xStream = GetGraphicReplacementStream(mpImpl->nViewAspect, mpImpl->mxObj, &mpImpl->aMediaType);
if(xStream.is())
{ if (mpImpl->pContainer)
{ bool bInsertGraphicStream = true;
uno::Reference<io::XSeekable> xSeekable(xStream, uno::UNO_QUERY);
std::optional<sal_Int64> oPosition; if (xSeekable.is())
{
oPosition = xSeekable->getPosition();
} if (bUpdate)
{
std::unique_ptr<SvStream> pResult = utl::UcbStreamHelper::CreateStream(xStream); if (pResult)
{
GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
Graphic aGraphic;
rGF.ImportGraphic(aGraphic, u"", *pResult); if (aGraphic.IsNone())
{ // The graphic is not something we can understand, don't overwrite a // potentially working previous graphic.
SAL_WARN("svtools.misc", "EmbeddedObjectRef::GetGraphicStream: failed to parse xStream");
bInsertGraphicStream = false;
}
}
} if (xSeekable.is() && oPosition.has_value())
{
xSeekable->seek(*oPosition);
} if (bInsertGraphicStream)
{
mpImpl->pContainer->InsertGraphicStream(xStream,mpImpl->aPersistName,mpImpl->aMediaType);
}
}
// Now scale text such that it fits in the rectangle // We start with the default size and decrease 1-AppFont for( sal_uInt16 i = 8; i > 2; i-- )
{
aPt.setX( (rRect.GetWidth() - pOut->GetTextWidth( rText )) / 2 );
aPt.setY( (rRect.GetHeight() - pOut->GetTextHeight()) / 2 );
if( mpImpl->pContainer )
{ //remove graphic from container thus a new up to date one is requested on save
mpImpl->pContainer->RemoveGraphicStream( mpImpl->aPersistName );
}
}
bool EmbeddedObjectRef::IsChart() const
{ //todo maybe for 3.0: //if the changes work good for chart //we should apply them for all own ole objects
//#i83708# #i81857# #i79578# request an ole replacement image only if really necessary //as this call can be very expensive and does block the user interface as long at it takes
void EmbeddedObjectRef::SetDefaultSizeForChart( const Size& rSizeIn_100TH_MM )
{ //#i103460# charts do not necessarily have an own size within ODF files, //for this case they need to use the size settings from the surrounding frame, //which is made available with this method
uno::Reference<chart2::XDefaultSizeTransmitter> xSizeTransmitter(mpImpl->mxObj, uno::UNO_QUERY);
DBG_ASSERT( xSizeTransmitter.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" ); if( xSizeTransmitter.is() )
xSizeTransmitter->setDefaultSize( mpImpl->aDefaultSizeForChart_In_100TH_MM );
}
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.