summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embeddedobj/source/commonembedding/embedobj.cxx60
-rw-r--r--embeddedobj/source/commonembedding/specialobject.cxx9
-rw-r--r--embeddedobj/source/inc/commonembobj.hxx3
-rw-r--r--embeddedobj/source/inc/specialobject.hxx7
-rw-r--r--include/svx/svdoole2.hxx17
-rw-r--r--include/svx/unoshape.hxx2
-rw-r--r--sc/source/ui/docshell/documentlinkmgr.cxx9
-rw-r--r--sfx2/source/doc/iframe.cxx55
-rw-r--r--svx/source/svdraw/svdoole2.cxx104
-rw-r--r--svx/source/unodraw/shapeimpl.hxx5
-rw-r--r--svx/source/unodraw/unoshap4.cxx23
-rw-r--r--sw/inc/ndole.hxx4
-rw-r--r--sw/source/core/ole/ndole.cxx89
-rw-r--r--xmloff/source/draw/ximpshap.cxx29
-rw-r--r--xmloff/source/draw/ximpshap.hxx2
15 files changed, 332 insertions, 86 deletions
diff --git a/embeddedobj/source/commonembedding/embedobj.cxx b/embeddedobj/source/commonembedding/embedobj.cxx
index e6e5bec2a316..b402dff22042 100644
--- a/embeddedobj/source/commonembedding/embedobj.cxx
+++ b/embeddedobj/source/commonembedding/embedobj.cxx
@@ -155,6 +155,37 @@ void OCommonEmbeddedObject::StateChangeNotification_Impl( bool bBeforeChange, sa
}
}
+void OCommonEmbeddedObject::SetInplaceActiveState()
+{
+ if ( !m_xClientSite.is() )
+ throw embed::WrongStateException( "client site not set, yet", *this );
+
+ uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
+ if ( !xInplaceClient.is() || !xInplaceClient->canInplaceActivate() )
+ throw embed::WrongStateException(); //TODO: can't activate inplace
+ xInplaceClient->activatingInplace();
+
+ uno::Reference< embed::XWindowSupplier > xClientWindowSupplier( xInplaceClient, uno::UNO_QUERY_THROW );
+
+ m_xClientWindow = xClientWindowSupplier->getWindow();
+ m_aOwnRectangle = xInplaceClient->getPlacement();
+ m_aClipRectangle = xInplaceClient->getClipRectangle();
+ awt::Rectangle aRectangleToShow = GetRectangleInterception( m_aOwnRectangle, m_aClipRectangle );
+
+ // create own window based on the client window
+ // place and resize the window according to the rectangles
+ uno::Reference< awt::XWindowPeer > xClientWindowPeer( m_xClientWindow, uno::UNO_QUERY_THROW );
+
+ // dispatch provider may not be provided
+ uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
+ bool bOk = m_xDocHolder->ShowInplace( xClientWindowPeer, aRectangleToShow, xContainerDP );
+ m_nObjectState = embed::EmbedStates::INPLACE_ACTIVE;
+ if ( !bOk )
+ {
+ SwitchStateTo_Impl( embed::EmbedStates::RUNNING );
+ throw embed::WrongStateException(); //TODO: can't activate inplace
+ }
+}
void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
{
@@ -228,34 +259,7 @@ void OCommonEmbeddedObject::SwitchStateTo_Impl( sal_Int32 nNextState )
{
if ( nNextState == embed::EmbedStates::INPLACE_ACTIVE )
{
- if ( !m_xClientSite.is() )
- throw embed::WrongStateException( "client site not set, yet", *this );
-
- uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );
- if ( !xInplaceClient.is() || !xInplaceClient->canInplaceActivate() )
- throw embed::WrongStateException(); //TODO: can't activate inplace
- xInplaceClient->activatingInplace();
-
- uno::Reference< embed::XWindowSupplier > xClientWindowSupplier( xInplaceClient, uno::UNO_QUERY_THROW );
-
- m_xClientWindow = xClientWindowSupplier->getWindow();
- m_aOwnRectangle = xInplaceClient->getPlacement();
- m_aClipRectangle = xInplaceClient->getClipRectangle();
- awt::Rectangle aRectangleToShow = GetRectangleInterception( m_aOwnRectangle, m_aClipRectangle );
-
- // create own window based on the client window
- // place and resize the window according to the rectangles
- uno::Reference< awt::XWindowPeer > xClientWindowPeer( m_xClientWindow, uno::UNO_QUERY_THROW );
-
- // dispatch provider may not be provided
- uno::Reference< frame::XDispatchProvider > xContainerDP = xInplaceClient->getInplaceDispatchProvider();
- bool bOk = m_xDocHolder->ShowInplace( xClientWindowPeer, aRectangleToShow, xContainerDP );
- m_nObjectState = nNextState;
- if ( !bOk )
- {
- SwitchStateTo_Impl( embed::EmbedStates::RUNNING );
- throw embed::WrongStateException(); //TODO: can't activate inplace
- }
+ SetInplaceActiveState();
}
else if ( nNextState == embed::EmbedStates::ACTIVE )
{
diff --git a/embeddedobj/source/commonembedding/specialobject.cxx b/embeddedobj/source/commonembedding/specialobject.cxx
index 683fe0aab3f2..c17a39accf2c 100644
--- a/embeddedobj/source/commonembedding/specialobject.cxx
+++ b/embeddedobj/source/commonembedding/specialobject.cxx
@@ -47,6 +47,7 @@ uno::Any SAL_CALL OSpecialEmbeddedObject::queryInterface( const uno::Type& rType
uno::Any aReturn = ::cppu::queryInterface( rType,
static_cast< embed::XEmbeddedObject* >( this ),
static_cast< embed::XInplaceObject* >( this ),
+ static_cast< embed::XCommonEmbedPersist* >( static_cast< embed::XEmbedPersist* >( this ) ),
static_cast< embed::XVisualObject* >( this ),
static_cast< embed::XClassifiedObject* >( this ),
static_cast< embed::XComponentSupplier* >( this ),
@@ -160,4 +161,12 @@ void SAL_CALL OSpecialEmbeddedObject::doVerb( sal_Int32 nVerbID )
OCommonEmbeddedObject::doVerb( nVerbID );
}
+void SAL_CALL OSpecialEmbeddedObject::reload(
+ const uno::Sequence< beans::PropertyValue >&,
+ const uno::Sequence< beans::PropertyValue >&)
+{
+ // Allow IFrames to reload their content
+ SetInplaceActiveState();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/inc/commonembobj.hxx b/embeddedobj/source/inc/commonembobj.hxx
index b2c9acd9ec1e..73282a00deac 100644
--- a/embeddedobj/source/inc/commonembobj.hxx
+++ b/embeddedobj/source/inc/commonembobj.hxx
@@ -226,6 +226,9 @@ private:
const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs );
+protected:
+ void SetInplaceActiveState();
+
public:
OCommonEmbeddedObject(
const css::uno::Reference< css::uno::XComponentContext >& rxContext,
diff --git a/embeddedobj/source/inc/specialobject.hxx b/embeddedobj/source/inc/specialobject.hxx
index 32ad61a7a582..4c4bc70db377 100644
--- a/embeddedobj/source/inc/specialobject.hxx
+++ b/embeddedobj/source/inc/specialobject.hxx
@@ -48,6 +48,13 @@ public:
virtual void SAL_CALL changeState( sal_Int32 nNewState ) override;
virtual void SAL_CALL doVerb( sal_Int32 nVerbID ) override;
+
+// XCommonEmbedPersist
+
+ virtual void SAL_CALL reload(
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ const css::uno::Sequence< css::beans::PropertyValue >& lObjArgs ) override;
+
};
#endif
diff --git a/include/svx/svdoole2.hxx b/include/svx/svdoole2.hxx
index b192a438bc19..085b6e04a3a3 100644
--- a/include/svx/svdoole2.hxx
+++ b/include/svx/svdoole2.hxx
@@ -42,6 +42,7 @@ namespace frame { class XModel; }
namespace svt { class EmbeddedObjectRef; }
class SdrOle2ObjImpl;
+class SvxOle2Shape;
class SVX_DLLPUBLIC SdrOle2Obj : public SdrRectObj
{
@@ -49,7 +50,7 @@ private:
std::unique_ptr<SdrOle2ObjImpl> mpImpl;
private:
- SVX_DLLPRIVATE void Connect_Impl();
+ SVX_DLLPRIVATE void Connect_Impl(SvxOle2Shape* pCreator = nullptr);
SVX_DLLPRIVATE void Disconnect_Impl();
SVX_DLLPRIVATE void AddListeners_Impl();
SVX_DLLPRIVATE void RemoveListeners_Impl();
@@ -105,7 +106,7 @@ public:
// OLE object has got a separate PersistName member now;
// !!! use ::SetPersistName( ... ) only, if you know what you do !!!
const OUString& GetPersistName() const;
- void SetPersistName( const OUString& rPersistName );
+ void SetPersistName( const OUString& rPersistName, SvxOle2Shape* pCreator = nullptr );
// One can add an application name to a SdrOle2Obj, which can be queried for
// later on (SD needs this for presentation objects).
@@ -153,7 +154,7 @@ public:
sal_Int64 nAspect );
static bool Unload( const css::uno::Reference< css::embed::XEmbeddedObject >& xObj, sal_Int64 nAspect );
bool Unload();
- void Connect();
+ void Connect(SvxOle2Shape* pCreator = nullptr);
void Disconnect();
void ObjectLoaded();
@@ -200,6 +201,16 @@ public:
void Connect() { GetRealObject(); }
};
+class SVX_DLLPUBLIC SdrIFrameLink final : public sfx2::SvBaseLink
+{
+ SdrOle2Obj* m_pObject;
+
+public:
+ explicit SdrIFrameLink(SdrOle2Obj* pObject);
+ virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
+ const OUString& rMimeType, const css::uno::Any & rValue ) override;
+};
+
#endif // INCLUDED_SVX_SVDOOLE2_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/unoshape.hxx b/include/svx/unoshape.hxx
index 0b48d1e433d6..712552a55281 100644
--- a/include/svx/unoshape.hxx
+++ b/include/svx/unoshape.hxx
@@ -597,6 +597,8 @@ public:
bool createObject( const SvGlobalName &aClassName );
void createLink( const OUString& aLinkURL );
+
+ virtual OUString GetAndClearInitialFrameURL();
};
diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx
index cb3467c8bb69..8ea3c2cce5fb 100644
--- a/sc/source/ui/docshell/documentlinkmgr.cxx
+++ b/sc/source/ui/docshell/documentlinkmgr.cxx
@@ -142,7 +142,7 @@ bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, boo
sfx2::SvBaseLink* pBase = rLink.get();
if (bDde && dynamic_cast<ScDdeLink*>(pBase))
return true;
- if (bOle && dynamic_cast<SdrEmbedObjectLink*>(pBase))
+ if (bOle && (dynamic_cast<SdrEmbedObjectLink*>(pBase) || dynamic_cast<SdrIFrameLink*>(pBase)))
return true;
if (bWebService && dynamic_cast<ScWebServiceLink*>(pBase))
return true;
@@ -173,6 +173,13 @@ bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(weld::Window* pWin)
continue;
}
+ SdrIFrameLink* pIFrameLink = dynamic_cast<SdrIFrameLink*>(pBase);
+ if (pIFrameLink)
+ {
+ pIFrameLink->Update();
+ continue;
+ }
+
ScWebServiceLink* pWebserviceLink = dynamic_cast<ScWebServiceLink*>(pBase);
if (pWebserviceLink)
{
diff --git a/sfx2/source/doc/iframe.cxx b/sfx2/source/doc/iframe.cxx
index 75f67b1a0f43..217c764e0272 100644
--- a/sfx2/source/doc/iframe.cxx
+++ b/sfx2/source/doc/iframe.cxx
@@ -180,31 +180,46 @@ sal_Bool SAL_CALL IFrameObject::load(
if (!SfxEvents_Impl::isScriptURLAllowed(aTargetURL.Complete))
return false;
+ bool bUpdateAllowed(true);
+ if (pDoc)
+ {
+ // perhaps should only check for file targets, but lets default to making it strong
+ // unless there is a known need to distinguish
+ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = pDoc->getEmbeddedObjectContainer();
+ bUpdateAllowed = rEmbeddedObjectContainer.getUserAllowsLinkUpdate();
+ }
+ if (!bUpdateAllowed)
+ return false;
+
OUString sReferer;
if (pDoc && pDoc->HasName())
sReferer = pDoc->GetMedium()->GetName();
- DBG_ASSERT( !mxFrame.is(), "Frame already existing!" );
- VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
- VclPtr<IFrameWindow_Impl> pWin = VclPtr<IFrameWindow_Impl>::Create( pParent, maFrmDescr.IsFrameBorderOn() );
- pWin->SetSizePixel( pParent->GetOutputSizePixel() );
- pWin->SetBackground();
- pWin->Show();
-
- uno::Reference < awt::XWindow > xWindow( pWin->GetComponentInterface(), uno::UNO_QUERY );
- xFrame->setComponent( xWindow, uno::Reference < frame::XController >() );
+ uno::Reference<css::awt::XWindow> xParentWindow(xFrame->getContainerWindow());
- // we must destroy the IFrame before the parent is destroyed
- xWindow->addEventListener( this );
-
- mxFrame = frame::Frame::create( mxContext );
- uno::Reference < awt::XWindow > xWin( pWin->GetComponentInterface(), uno::UNO_QUERY );
- mxFrame->initialize( xWin );
- mxFrame->setName( maFrmDescr.GetName() );
-
- uno::Reference < frame::XFramesSupplier > xFramesSupplier( xFrame, uno::UNO_QUERY );
- if ( xFramesSupplier.is() )
- mxFrame->setCreator( xFramesSupplier );
+ if (!mxFrame.is())
+ {
+ VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(xParentWindow);
+ VclPtr<IFrameWindow_Impl> pWin = VclPtr<IFrameWindow_Impl>::Create( pParent, maFrmDescr.IsFrameBorderOn() );
+ pWin->SetSizePixel( pParent->GetOutputSizePixel() );
+ pWin->SetBackground();
+ pWin->Show();
+
+ uno::Reference < awt::XWindow > xWindow( pWin->GetComponentInterface(), uno::UNO_QUERY );
+ xFrame->setComponent( xWindow, uno::Reference < frame::XController >() );
+
+ // we must destroy the IFrame before the parent is destroyed
+ xWindow->addEventListener( this );
+
+ mxFrame = frame::Frame::create( mxContext );
+ uno::Reference < awt::XWindow > xWin( pWin->GetComponentInterface(), uno::UNO_QUERY );
+ mxFrame->initialize( xWin );
+ mxFrame->setName( maFrmDescr.GetName() );
+
+ uno::Reference < frame::XFramesSupplier > xFramesSupplier( xFrame, uno::UNO_QUERY );
+ if ( xFramesSupplier.is() )
+ mxFrame->setCreator( xFramesSupplier );
+ }
uno::Sequence < beans::PropertyValue > aProps(3);
aProps[0].Name = "PluginMode";
diff --git a/svx/source/svdraw/svdoole2.cxx b/svx/source/svdraw/svdoole2.cxx
index 8b4faca5f1d3..91a016e9ac93 100644
--- a/svx/source/svdraw/svdoole2.cxx
+++ b/svx/source/svdraw/svdoole2.cxx
@@ -78,6 +78,7 @@
#include <sdr/contact/viewcontactofsdrole2obj.hxx>
#include <svx/svdograf.hxx>
#include <sdr/properties/oleproperties.hxx>
+#include <svx/unoshape.hxx>
#include <svx/xlineit0.hxx>
#include <svx/xlnclit.hxx>
#include <svx/xbtmpit.hxx>
@@ -598,6 +599,35 @@ void SdrEmbedObjectLink::Closed()
SvBaseLink::Closed();
}
+SdrIFrameLink::SdrIFrameLink(SdrOle2Obj* pObject)
+ : ::sfx2::SvBaseLink(::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB)
+ , m_pObject(pObject)
+{
+ SetSynchron( false );
+}
+
+::sfx2::SvBaseLink::UpdateResult SdrIFrameLink::DataChanged(
+ const OUString&, const uno::Any& )
+{
+ uno::Reference<embed::XEmbeddedObject> xObject = m_pObject->GetObjRef();
+ uno::Reference<embed::XCommonEmbedPersist> xPersObj(xObject, uno::UNO_QUERY);
+ if (xPersObj.is())
+ {
+ // let the IFrameObject reload the link
+ try
+ {
+ xPersObj->reload(uno::Sequence<beans::PropertyValue>(), uno::Sequence<beans::PropertyValue>());
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ m_pObject->SetChanged();
+ }
+
+ return SUCCESS;
+}
+
class SdrOle2ObjImpl
{
public:
@@ -615,7 +645,7 @@ public:
bool mbLoadingOLEObjectFailed:1; // New local var to avoid repeated loading if load of OLE2 fails
bool mbConnected:1;
- SdrEmbedObjectLink* mpObjectLink;
+ sfx2::SvBaseLink* mpObjectLink;
OUString maLinkURL;
rtl::Reference<SvxUnoShapeModifyListener> mxModifyListener;
@@ -815,7 +845,7 @@ bool SdrOle2Obj::IsEmpty() const
return !mpImpl->mxObjRef.is();
}
-void SdrOle2Obj::Connect()
+void SdrOle2Obj::Connect(SvxOle2Shape* pCreator)
{
if( IsEmptyPresObj() )
return;
@@ -828,7 +858,7 @@ void SdrOle2Obj::Connect()
return;
}
- Connect_Impl();
+ Connect_Impl(pCreator);
AddListeners_Impl();
}
@@ -928,24 +958,51 @@ void SdrOle2Obj::CheckFileLink_Impl()
try
{
- uno::Reference< embed::XLinkageSupport > xLinkSupport( mpImpl->mxObjRef.GetObject(), uno::UNO_QUERY );
+ uno::Reference<embed::XEmbeddedObject> xObject = mpImpl->mxObjRef.GetObject();
+ if (!xObject)
+ return;
- if ( xLinkSupport.is() && xLinkSupport->isLink() )
- {
- OUString aLinkURL = xLinkSupport->getLinkURL();
+ bool bIFrame = false;
- if ( !aLinkURL.isEmpty() )
+ OUString aLinkURL;
+ uno::Reference<embed::XLinkageSupport> xLinkSupport(xObject, uno::UNO_QUERY);
+ if (xLinkSupport)
+ {
+ if (xLinkSupport->isLink())
+ aLinkURL = xLinkSupport->getLinkURL();
+ }
+ else
+ {
+ // get IFrame (Floating Frames) listed and updatable from the
+ // manage links dialog
+ SvGlobalName aClassId(xObject->getClassID());
+ if (aClassId == SvGlobalName(SO3_IFRAME_CLASSID))
{
- // this is a file link so the model link manager should handle it
- sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
+ uno::Reference<beans::XPropertySet> xSet(xObject->getComponent(), uno::UNO_QUERY);
+ if (xSet.is())
+ xSet->getPropertyValue("FrameURL") >>= aLinkURL;
+ bIFrame = true;
+ }
+ }
+
+ if (!aLinkURL.isEmpty()) // this is a file link so the model link manager should handle it
+ {
+ sfx2::LinkManager* pLinkManager(getSdrModelFromSdrObject().GetLinkManager());
- if ( pLinkManager )
+ if ( pLinkManager )
+ {
+ SdrEmbedObjectLink* pEmbedObjectLink = nullptr;
+ if (!bIFrame)
{
- mpImpl->mpObjectLink = new SdrEmbedObjectLink( this );
- mpImpl->maLinkURL = aLinkURL;
- pLinkManager->InsertFileLink( *mpImpl->mpObjectLink, OBJECT_CLIENT_OLE, aLinkURL );
- mpImpl->mpObjectLink->Connect();
+ pEmbedObjectLink = new SdrEmbedObjectLink(this);
+ mpImpl->mpObjectLink = pEmbedObjectLink;
}
+ else
+ mpImpl->mpObjectLink = new SdrIFrameLink(this);
+ mpImpl->maLinkURL = aLinkURL;
+ pLinkManager->InsertFileLink( *mpImpl->mpObjectLink, OBJECT_CLIENT_OLE, aLinkURL );
+ if (pEmbedObjectLink)
+ pEmbedObjectLink->Connect();
}
}
}
@@ -955,7 +1012,7 @@ void SdrOle2Obj::CheckFileLink_Impl()
}
}
-void SdrOle2Obj::Connect_Impl()
+void SdrOle2Obj::Connect_Impl(SvxOle2Shape* pCreator)
{
if(mpImpl->aPersistName.isEmpty() )
return;
@@ -996,6 +1053,17 @@ void SdrOle2Obj::Connect_Impl()
}
}
+ if (pCreator)
+ {
+ OUString sFrameURL(pCreator->GetAndClearInitialFrameURL());
+ if (!sFrameURL.isEmpty() && svt::EmbeddedObjectRef::TryRunningState(mpImpl->mxObjRef.GetObject()))
+ {
+ uno::Reference<beans::XPropertySet> xSet(mpImpl->mxObjRef->getComponent(), uno::UNO_QUERY);
+ if (xSet.is())
+ xSet->setPropertyValue("FrameURL", uno::Any(sFrameURL));
+ }
+ }
+
if ( mpImpl->mxObjRef.is() )
{
if ( !mpImpl->mxLightClient.is() )
@@ -1308,14 +1376,14 @@ SdrObjectUniquePtr SdrOle2Obj::getFullDragClone() const
return createSdrGrafObjReplacement(false);
}
-void SdrOle2Obj::SetPersistName( const OUString& rPersistName )
+void SdrOle2Obj::SetPersistName( const OUString& rPersistName, SvxOle2Shape* pCreator )
{
DBG_ASSERT( mpImpl->aPersistName.isEmpty(), "Persist name changed!");
mpImpl->aPersistName = rPersistName;
mpImpl->mbLoadingOLEObjectFailed = false;
- Connect();
+ Connect(pCreator);
SetChanged();
}
diff --git a/svx/source/unodraw/shapeimpl.hxx b/svx/source/unodraw/shapeimpl.hxx
index a1a4e6963020..4381094d380a 100644
--- a/svx/source/unodraw/shapeimpl.hxx
+++ b/svx/source/unodraw/shapeimpl.hxx
@@ -64,8 +64,11 @@ public:
virtual void Create( SdrObject* pNewOpj, SvxDrawPage* pNewPage ) override;
};
+
class SvxFrameShape : public SvxOle2Shape
{
+private:
+ OUString m_sInitialFrameURL;
protected:
// override these for special property handling in subcasses. Return true if property is handled
virtual bool setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const css::uno::Any& rValue ) override;
@@ -82,6 +85,8 @@ public:
virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override;
virtual void Create( SdrObject* pNewOpj, SvxDrawPage* pNewPage ) override;
+
+ virtual OUString GetAndClearInitialFrameURL() override;
};
diff --git a/svx/source/unodraw/unoshap4.cxx b/svx/source/unodraw/unoshap4.cxx
index f7629f338858..6dc18d6cf9e4 100644
--- a/svx/source/unodraw/unoshap4.cxx
+++ b/svx/source/unodraw/unoshap4.cxx
@@ -180,7 +180,7 @@ bool SvxOle2Shape::setPropertyValueImpl( const OUString& rName, const SfxItemPro
#else
pOle = static_cast<SdrOle2Obj*>(GetSdrObject());
#endif
- pOle->SetPersistName( aPersistName );
+ pOle->SetPersistName( aPersistName, this );
return true;
}
break;
@@ -501,10 +501,11 @@ void SvxOle2Shape::createLink( const OUString& aLinkURL )
void SvxOle2Shape::resetModifiedState()
{
- ::comphelper::IEmbeddedHelper* pPersist = GetSdrObject()->getSdrModelFromSdrObject().GetPersist();
+ SdrObject* pObject = GetSdrObject();
+ ::comphelper::IEmbeddedHelper* pPersist = pObject ? pObject->getSdrModelFromSdrObject().GetPersist() : nullptr;
if( pPersist && !pPersist->isEnableSetModified() )
{
- SdrOle2Obj* pOle = dynamic_cast< SdrOle2Obj* >( GetSdrObject() );
+ SdrOle2Obj* pOle = dynamic_cast< SdrOle2Obj* >(pObject);
if( pOle && !pOle->IsEmpty() )
{
uno::Reference < util::XModifiable > xMod( pOle->GetObjRef(), uno::UNO_QUERY );
@@ -554,6 +555,11 @@ SvGlobalName SvxOle2Shape::GetClassName_Impl(OUString& rHexCLSID)
return aClassName;
}
+OUString SvxOle2Shape::GetAndClearInitialFrameURL()
+{
+ return OUString();
+}
+
SvxAppletShape::SvxAppletShape(SdrObject* pObject)
: SvxOle2Shape( pObject, getSvxMapProvider().GetMap(SVXMAP_APPLET), getSvxMapProvider().GetPropertySet(SVXMAP_APPLET, SdrObject::GetGlobalDrawObjectItemPool()) )
{
@@ -707,8 +713,19 @@ SvxFrameShape::~SvxFrameShape() throw()
{
}
+OUString SvxFrameShape::GetAndClearInitialFrameURL()
+{
+ OUString sRet(m_sInitialFrameURL);
+ m_sInitialFrameURL.clear();
+ return sRet;
+}
+
void SvxFrameShape::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
{
+ uno::Reference<beans::XPropertySet> xSet(static_cast<OWeakObject *>(this), uno::UNO_QUERY);
+ if (xSet)
+ xSet->getPropertyValue("FrameURL") >>= m_sInitialFrameURL;
+
SvxShape::Create( pNewObj, pNewPage );
const SvGlobalName aIFrameClassId( SO3_IFRAME_CLASSID );
createObject(aIFrameClassId);
diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx
index b413d5af187d..470ea17563f8 100644
--- a/sw/inc/ndole.hxx
+++ b/sw/inc/ndole.hxx
@@ -28,7 +28,7 @@ class SwGrfFormatColl;
class SwDoc;
class SwOLENode;
class SwOLEListener_Impl;
-class SwEmbedObjectLink;
+namespace sfx2 { class SvBaseLink; }
class DeflateData;
class SW_DLLPUBLIC SwOLEObj
@@ -90,7 +90,7 @@ class SW_DLLPUBLIC SwOLENode: public SwNoTextNode
bool mbOLESizeInvalid; /**< Should be considered at SwDoc::PrtOLENotify
(e.g. copied). Is not persistent. */
- SwEmbedObjectLink* mpObjectLink;
+ sfx2::SvBaseLink* mpObjectLink;
OUString maLinkURL;
SwOLENode( const SwNodeIndex &rWhere,
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index 9613136edc8e..5094b9f777a1 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -147,6 +147,8 @@ void SAL_CALL SwOLEListener_Impl::disposing( const lang::EventObject& )
// TODO/LATER: actually SwEmbedObjectLink should be used here, but because different objects are used to control
// embedded object different link objects with the same functionality had to be implemented
+namespace {
+
class SwEmbedObjectLink : public sfx2::SvBaseLink
{
SwOLENode* pOleNode;
@@ -209,6 +211,44 @@ void SwEmbedObjectLink::Closed()
SvBaseLink::Closed();
}
+class SwIFrameLink : public sfx2::SvBaseLink
+{
+ SwOLENode* m_pOleNode;
+
+public:
+ explicit SwIFrameLink(SwOLENode* pNode)
+ : ::sfx2::SvBaseLink(::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB)
+ , m_pOleNode(pNode)
+ {
+ SetSynchron( false );
+ }
+
+ ::sfx2::SvBaseLink::UpdateResult DataChanged(
+ const OUString&, const uno::Any& )
+ {
+ uno::Reference<embed::XEmbeddedObject> xObject = m_pOleNode->GetOLEObj().GetOleRef();
+ uno::Reference<embed::XCommonEmbedPersist> xPersObj(xObject, uno::UNO_QUERY);
+ if (xPersObj.is())
+ {
+ // let the IFrameObject reload the link
+ try
+ {
+ xPersObj->reload(uno::Sequence<beans::PropertyValue>(), uno::Sequence<beans::PropertyValue>());
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ m_pOleNode->SetChanged();
+ }
+
+ return SUCCESS;
+ }
+
+};
+
+}
+
SwOLENode::SwOLENode( const SwNodeIndex &rWhere,
const svt::EmbeddedObjectRef& xObj,
SwGrfFormatColl *pGrfColl,
@@ -607,18 +647,49 @@ void SwOLENode::CheckFileLink_Impl()
try
{
- uno::Reference< embed::XLinkageSupport > xLinkSupport( maOLEObj.m_xOLERef.GetObject(), uno::UNO_QUERY_THROW );
- if ( xLinkSupport->isLink() )
+ uno::Reference<embed::XEmbeddedObject> xObject = maOLEObj.m_xOLERef.GetObject();
+ if (!xObject)
+ return;
+
+ bool bIFrame = false;
+
+ OUString aLinkURL;
+ uno::Reference<embed::XLinkageSupport> xLinkSupport(xObject, uno::UNO_QUERY);
+ if (xLinkSupport)
{
- const OUString aLinkURL = xLinkSupport->getLinkURL();
- if ( !aLinkURL.isEmpty() )
+ if (xLinkSupport->isLink())
+ aLinkURL = xLinkSupport->getLinkURL();
+ }
+ else
+ {
+ // get IFrame (Floating Frames) listed and updatable from the
+ // manage links dialog
+ SvGlobalName aClassId(xObject->getClassID());
+ if (aClassId == SvGlobalName(SO3_IFRAME_CLASSID))
+ {
+ uno::Reference<beans::XPropertySet> xSet(xObject->getComponent(), uno::UNO_QUERY);
+ if (xSet.is())
+ xSet->getPropertyValue("FrameURL") >>= aLinkURL;
+ bIFrame = true;
+ }
+ }
+
+ if (!aLinkURL.isEmpty()) // this is a file link so the model link manager should handle it
+ {
+ SwEmbedObjectLink* pEmbedObjectLink = nullptr;
+ if (!bIFrame)
+ {
+ pEmbedObjectLink = new SwEmbedObjectLink(this);
+ mpObjectLink = pEmbedObjectLink;
+ }
+ else
{
- // this is a file link so the model link manager should handle it
- mpObjectLink = new SwEmbedObjectLink( this );
- maLinkURL = aLinkURL;
- GetDoc()->getIDocumentLinksAdministration().GetLinkManager().InsertFileLink( *mpObjectLink, OBJECT_CLIENT_OLE, aLinkURL );
- mpObjectLink->Connect();
+ mpObjectLink = new SwIFrameLink(this);
}
+ maLinkURL = aLinkURL;
+ GetDoc()->getIDocumentLinksAdministration().GetLinkManager().InsertFileLink( *mpObjectLink, OBJECT_CLIENT_OLE, aLinkURL );
+ if (pEmbedObjectLink)
+ pEmbedObjectLink->Connect();
}
}
catch( uno::Exception& )
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index a7f2f2f76f1b..44b5177501f1 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -3223,9 +3223,35 @@ SdXMLFloatingFrameShapeContext::~SdXMLFloatingFrameShapeContext()
{
}
+uno::Reference<drawing::XShape> SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape() const
+{
+ uno::Reference<lang::XMultiServiceFactory> xServiceFact(GetImport().GetModel(), uno::UNO_QUERY);
+ if (!xServiceFact.is())
+ return nullptr;
+ uno::Reference<drawing::XShape> xShape(
+ xServiceFact->createInstance("com.sun.star.drawing.FrameShape"), uno::UNO_QUERY);
+ return xShape;
+}
+
void SdXMLFloatingFrameShapeContext::StartElement( const css::uno::Reference< css::xml::sax::XAttributeList >& )
{
- AddShape("com.sun.star.drawing.FrameShape");
+ uno::Reference<drawing::XShape> xShape(SdXMLFloatingFrameShapeContext::CreateFloatingFrameShape());
+
+ uno::Reference< beans::XPropertySet > xProps(xShape, uno::UNO_QUERY);
+ // set FrameURL before AddShape, we have to do it again later because it
+ // gets cleared when the SdrOle2Obj is attached to the XShape. But we want
+ // FrameURL to exist when AddShape triggers SetPersistName which itself
+ // triggers SdrOle2Obj::CheckFileLink_Impl and at that point we want to
+ // know what URL will end up being used. So bodge this by setting FrameURL
+ // to the temp pre-SdrOle2Obj attached properties and we can smuggle it
+ // eventually into SdrOle2Obj::SetPersistName at the right point after
+ // PersistName is set but before SdrOle2Obj::CheckFileLink_Impl is called
+ // in order to inform the link manager that this is an IFrame that links to
+ // a URL
+ if (xProps && !maHref.isEmpty())
+ xProps->setPropertyValue("FrameURL", Any(maHref));
+
+ AddShape(xShape);
if( mxShape.is() )
{
@@ -3234,7 +3260,6 @@ void SdXMLFloatingFrameShapeContext::StartElement( const css::uno::Reference< cs
// set pos, size, shear and rotate
SetTransformation();
- uno::Reference< beans::XPropertySet > xProps( mxShape, uno::UNO_QUERY );
if( xProps.is() )
{
if( !maFrameName.isEmpty() )
diff --git a/xmloff/source/draw/ximpshap.hxx b/xmloff/source/draw/ximpshap.hxx
index fae45f88f00a..a00c87e8a0da 100644
--- a/xmloff/source/draw/ximpshap.hxx
+++ b/xmloff/source/draw/ximpshap.hxx
@@ -513,6 +513,8 @@ private:
OUString maFrameName;
OUString maHref;
+ css::uno::Reference<css::drawing::XShape> CreateFloatingFrameShape() const;
+
public:
SdXMLFloatingFrameShapeContext( SvXMLImport& rImport, sal_uInt16 nPrfx,