summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-11-25 14:53:04 +0100
committerMiklos Vajna <vmiklos@collabora.com>2021-11-25 15:49:05 +0100
commit4f9f1ac33366817df61c488a9f36b09c592ee939 (patch)
treeb11c7dda23f40d60f833c0c991851d79ea4d5cc6
parent9bc77b5107917ffe96b7ddf2c4d6d739a5e60c5b (diff)
sw: allow viewing OLE objects in protected sections
The problem was that we don't allow even opening embedded objects in protected sections, which means the content of multi-page embedded objects can't even be viewed in protected sections, which probably goes too far. Fix this relaxing the condition in SwEditWin::MouseButtonDown() to allow launching the OLE object on double-click, and then make sure that the native data is not updated in SfxInPlaceClient_Impl::saveObject() and the replacement image is not updated in svt::EmbedEventListener_Impl::stateChanged(). This is complicated by only the Writer layout knowing if a given OLE object is anchored in a protected frame, so pass down a callback to sfx2/ and svtools/ to check if the OLE object is protected. Not copying the protected bit has the benefit of behaving correctly if the section turns into non-protected: copying would not work properly, as SfxInPlaceClient is created on demand, so not re-created when the protectedness of the section is changed. Change-Id: Ib3a8f2092d27dc1ebd3ef355c95a4a473988b163 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125815 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--include/sfx2/ipclient.hxx2
-rw-r--r--include/svtools/embedhlp.hxx4
-rw-r--r--sfx2/source/view/ipclient.cxx4
-rw-r--r--svtools/source/misc/embedhlp.cxx21
-rw-r--r--sw/inc/ndole.hxx3
-rw-r--r--sw/inc/swcli.hxx2
-rw-r--r--sw/source/core/ole/ndole.cxx32
-rw-r--r--sw/source/uibase/app/docsh.cxx16
-rw-r--r--sw/source/uibase/docvw/edtwin.cxx14
-rw-r--r--sw/source/uibase/uiview/swcli.cxx25
10 files changed, 114 insertions, 9 deletions
diff --git a/include/sfx2/ipclient.hxx b/include/sfx2/ipclient.hxx
index 180f67b54588..3e219514a6f1 100644
--- a/include/sfx2/ipclient.hxx
+++ b/include/sfx2/ipclient.hxx
@@ -88,6 +88,8 @@ public:
bool IsUIActive() const;
virtual void FormatChanged(); // object format was changed (used for StarMath formulas aligning)
+
+ virtual bool IsProtected() const;
};
#endif
diff --git a/include/svtools/embedhlp.hxx b/include/svtools/embedhlp.hxx
index 43d0b64461dd..05b0b5644122 100644
--- a/include/svtools/embedhlp.hxx
+++ b/include/svtools/embedhlp.hxx
@@ -107,6 +107,10 @@ public:
bool is() const;
bool IsLocked() const;
+
+ void SetIsProtectedHdl(const Link<LinkParamNone*, bool>& rProtectedHdl);
+ Link<LinkParamNone*, bool> GetIsProtectedHdl() const;
+
bool IsChart() const;
OUString GetChartType();
diff --git a/sfx2/source/view/ipclient.cxx b/sfx2/source/view/ipclient.cxx
index eef20a921171..08898ba1573f 100644
--- a/sfx2/source/view/ipclient.cxx
+++ b/sfx2/source/view/ipclient.cxx
@@ -212,7 +212,7 @@ uno::Reference < frame::XFrame > const & SfxInPlaceClient_Impl::GetFrame() const
void SAL_CALL SfxInPlaceClient_Impl::saveObject()
{
- if ( !m_bStoreObject )
+ if (!m_bStoreObject || m_pClient->IsProtected())
// client wants to discard the object (usually it means the container document is closed while an object is active
// and the user didn't request saving the changes
return;
@@ -1044,6 +1044,8 @@ void SfxInPlaceClient::FormatChanged()
// dummy implementation
}
+bool SfxInPlaceClient::IsProtected() const { return false; }
+
void SfxInPlaceClient::DeactivateObject()
{
if ( !GetObject().is() )
diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
index b37209e891de..1ef6cd579b0e 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -137,9 +137,16 @@ void SAL_CALL EmbedEventListener_Impl::stateChanged( const lang::EventObject&,
uno::Reference < util::XModifiable > xMod( pObject->GetObject()->getComponent(), uno::UNO_QUERY );
if ( nNewState == embed::EmbedStates::RUNNING )
{
+ bool bProtected = false;
+ if (pObject->GetIsProtectedHdl().IsSet())
+ {
+ bProtected = pObject->GetIsProtectedHdl().Call(nullptr);
+ }
+
// 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() )
+ if ((pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON)
+ && nOldState != embed::EmbedStates::LOADED && !pObject->IsChart() && !bProtected)
// get new replacement after deactivation
pObject->UpdateReplacement();
@@ -241,6 +248,8 @@ struct EmbeddedObjectRef_Impl
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
+ Link<LinkParamNone*, bool> m_aIsProtectedHdl;
+
EmbeddedObjectRef_Impl() :
pContainer(nullptr),
nViewAspect(embed::Aspects::MSOLE_CONTENT),
@@ -396,6 +405,16 @@ bool EmbeddedObjectRef::IsLocked() const
return mpImpl->bIsLocked;
}
+void EmbeddedObjectRef::SetIsProtectedHdl(const Link<LinkParamNone*, bool>& rProtectedHdl)
+{
+ mpImpl->m_aIsProtectedHdl = rProtectedHdl;
+}
+
+Link<LinkParamNone*, bool> EmbeddedObjectRef::GetIsProtectedHdl() const
+{
+ return mpImpl->m_aIsProtectedHdl;
+}
+
void EmbeddedObjectRef::GetReplacement( bool bUpdate )
{
Graphic aOldGraphic;
diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx
index 9603ce4f4440..302c9a0a5ebe 100644
--- a/sw/inc/ndole.hxx
+++ b/sw/inc/ndole.hxx
@@ -52,6 +52,8 @@ class SW_DLLPUBLIC SwOLEObj
void SetNode( SwOLENode* pNode );
+ DECL_LINK(IsProtectedHdl, LinkParamNone*, bool);
+
public:
SwOLEObj( const svt::EmbeddedObjectRef& pObj );
SwOLEObj( const OUString &rName, sal_Int64 nAspect );
@@ -69,6 +71,7 @@ public:
const OUString& GetCurrentPersistName() const { return m_aName; }
OUString GetStyleString();
bool IsOleRef() const; ///< To avoid unnecessary loading of object.
+ bool IsProtected() const;
// try to get OLE visualization in form of a Primitive2DSequence
// and the corresponding B2DRange. This data may be locally buffered
diff --git a/sw/inc/swcli.hxx b/sw/inc/swcli.hxx
index fc79dc1cb18c..d50ebcb3f95c 100644
--- a/sw/inc/swcli.hxx
+++ b/sw/inc/swcli.hxx
@@ -44,6 +44,8 @@ public:
bool IsCheckForOLEInCaption() const { return m_IsOldCheckForOLEInCaption; }
virtual void FormatChanged() override;
+
+ bool IsProtected() const override;
};
#endif
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index ee18e029a28d..d553768db7ce 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -57,6 +57,7 @@
#include <libxml/xmlwriter.h>
#include <sfx2/xmldump.hxx>
#include <osl/diagnose.h>
+#include <flyfrm.hxx>
using namespace utl;
using namespace com::sun::star::uno;
@@ -906,6 +907,36 @@ bool SwOLEObj::IsOleRef() const
return m_xOLERef.is();
}
+IMPL_LINK_NOARG(SwOLEObj, IsProtectedHdl, LinkParamNone*, bool) { return IsProtected(); }
+
+bool SwOLEObj::IsProtected() const
+{
+ if (!m_pOLENode)
+ {
+ return false;
+ }
+
+ SwFrame* pFrame = m_pOLENode->getLayoutFrame(nullptr);
+ if (!pFrame)
+ {
+ return false;
+ }
+ SwFrame* pUpper = pFrame->GetUpper();
+ if (!pUpper || !pUpper->IsFlyFrame())
+ {
+ return false;
+ }
+
+ auto pFlyFrame = static_cast<SwFlyFrame*>(pUpper);
+ const SwFrame* pAnchor = pFlyFrame->GetAnchorFrame();
+ if (!pAnchor)
+ {
+ return false;
+ }
+
+ return pAnchor->IsProtected();
+}
+
uno::Reference < embed::XEmbeddedObject > const & SwOLEObj::GetOleRef()
{
if( !m_xOLERef.is() )
@@ -939,6 +970,7 @@ uno::Reference < embed::XEmbeddedObject > const & SwOLEObj::GetOleRef()
}
if (xObj.is())
{
+ m_xOLERef.SetIsProtectedHdl(LINK(this, SwOLEObj, IsProtectedHdl));
m_xOLERef.Assign( xObj, m_xOLERef.GetViewAspect() );
m_xOLERef.AssignToContainer( &p->GetEmbeddedObjectContainer(), m_aName );
m_xListener = new SwOLEListener_Impl( this );
diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx
index cf5b011d02f8..facceefc11e7 100644
--- a/sw/source/uibase/app/docsh.cxx
+++ b/sw/source/uibase/app/docsh.cxx
@@ -1134,6 +1134,22 @@ void SwDocShell::GetState(SfxItemSet& rSet)
// OLE-Hdls
IMPL_LINK( SwDocShell, Ole2ModifiedHdl, bool, bNewStatus, void )
{
+ if (m_pWrtShell)
+ {
+ SwOLENode* pOLENode = nullptr;
+ if (!m_pWrtShell->IsTableMode())
+ {
+ pOLENode = m_pWrtShell->GetCursor()->GetNode().GetOLENode();
+ }
+ if (pOLENode)
+ {
+ if (pOLENode->GetOLEObj().IsProtected())
+ {
+ return;
+ }
+ }
+ }
+
if( IsEnableSetModified() )
SetModified( bNewStatus );
}
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 85e5eb8fb275..45139e673912 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -3282,8 +3282,11 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
case 2:
{
g_bFrameDrag = false;
- if ( !bIsDocReadOnly && rSh.IsInsideSelectedObj(aDocPos) &&
- FlyProtectFlags::NONE == rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) )
+ if (!bIsDocReadOnly && rSh.IsInsideSelectedObj(aDocPos)
+ && (FlyProtectFlags::NONE
+ == rSh.IsSelObjProtected(FlyProtectFlags::Content
+ | FlyProtectFlags::Parent)
+ || rSh.GetSelectionType() == SelectionType::Ole))
{
/* This is no good: on the one hand GetSelectionType is used as flag field
* (take a look into the GetSelectionType method) and on the other hand the
@@ -3303,11 +3306,8 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
// double click on OLE object --> OLE-InPlace
case SelectionType::Ole:
- if (rSh.IsSelObjProtected(FlyProtectFlags::Content) == FlyProtectFlags::NONE)
- {
- RstMBDownFlags();
- rSh.LaunchOLEObj();
- }
+ RstMBDownFlags();
+ rSh.LaunchOLEObj();
return;
case SelectionType::Frame:
diff --git a/sw/source/uibase/uiview/swcli.cxx b/sw/source/uibase/uiview/swcli.cxx
index b3d312b07e5c..b8c7fc7b7a46 100644
--- a/sw/source/uibase/uiview/swcli.cxx
+++ b/sw/source/uibase/uiview/swcli.cxx
@@ -30,6 +30,8 @@
#include <toolkit/helper/vclunohelper.hxx>
+#include <ndole.hxx>
+
using namespace com::sun::star;
SwOleClient::SwOleClient(SwView *pView, SwEditWin *pWin, const svt::EmbeddedObjectRef& xObj)
@@ -165,4 +167,27 @@ void SwOleClient::FormatChanged()
}
}
+bool SwOleClient::IsProtected() const
+{
+ auto pView = dynamic_cast<SwView*>(GetViewShell());
+ if (!pView)
+ {
+ return false;
+ }
+
+ SwWrtShell& rWrtSh = pView->GetWrtShell();
+ if (rWrtSh.IsTableMode())
+ {
+ return false;
+ }
+
+ SwOLENode* pOLENode = rWrtSh.GetCursor()->GetNode().GetOLENode();
+ if (!pOLENode)
+ {
+ return false;
+ }
+
+ return pOLENode->GetOLEObj().IsProtected();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */