embeddedobj/source/commonembedding/miscobj.cxx     |   22 ++++++++++++++
 embeddedobj/source/commonembedding/persistence.cxx |    5 +++
 embeddedobj/source/inc/commonembobj.hxx            |    5 +++
 include/sfx2/ipclient.hxx                          |    2 +
 include/svtools/embedhlp.hxx                       |    4 ++
 sfx2/source/view/ipclient.cxx                      |    4 +-
 svtools/source/misc/embedhlp.cxx                   |   21 +++++++++++++
 sw/inc/ndole.hxx                                   |    3 +
 sw/inc/swcli.hxx                                   |    2 +
 sw/source/core/ole/ndole.cxx                       |   32 +++++++++++++++++++++
 sw/source/uibase/app/docsh.cxx                     |   16 ++++++++++
 sw/source/uibase/docvw/edtwin.cxx                  |   14 ++++-----
 sw/source/uibase/uiview/swcli.cxx                  |   25 ++++++++++++++++
 sw/source/uibase/wrtsh/wrtsh1.cxx                  |   10 ++++++
 14 files changed, 156 insertions(+), 9 deletions(-)

New commits:
commit 0ab465a690daa9378f771d1d99f1119ad5b6fb2d
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Nov 26 08:45:24 2021 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Nov 26 13:30:28 2021 +0100

    sw, viewing OLE objects: also protect "common" embeded objects
    
    Commit 4f9f1ac33366817df61c488a9f36b09c592ee939 (sw: allow viewing OLE
    objects in protected sections, 2021-11-25) allowed launching OLE objects
    in protected sections, and then made sure that changes done in "real"
    OLE editors (on Windows) are discarded: both the native data and
    preview.
    
    Extend this mechanism to also handle common embedded objects (i.e. when
    we load the data into an own document model, like Calc-in-Writer on
    Linux): there we can simply load the data read-only, so there will be no
    need to discard anything.
    
    This requires some way to pass down the read-only flag from sw/ to
    embeddedobj, implement XInitialization on OCommonEmbeddedObject to do
    that.
    
    (cherry picked from commit 32842d4bf250bcab281eb71a218d618485c60290)
    
    Conflicts:
            sw/source/uibase/wrtsh/wrtsh1.cxx
    
    Change-Id: I7b32d7514a6b0a40b4f58bed57879d292daa4ed7

diff --git a/embeddedobj/source/commonembedding/miscobj.cxx 
b/embeddedobj/source/commonembedding/miscobj.cxx
index 8a1dd801f6ea..3f4414b8118a 100644
--- a/embeddedobj/source/commonembedding/miscobj.cxx
+++ b/embeddedobj/source/commonembedding/miscobj.cxx
@@ -33,6 +33,7 @@
 
 #include <vcl/svapp.hxx>
 #include <cppuhelper/supportsservice.hxx>
+#include <comphelper/sequenceashashmap.hxx>
 
 #include "persistence.hxx"
 
@@ -347,6 +348,11 @@ uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( 
const uno::Type& rType
         void* p = static_cast<lang::XServiceInfo*>(this);
         return uno::Any(&p, rType);
     }
+    else if (rType == cppu::UnoType<lang::XInitialization>::get())
+    {
+        void* p = static_cast<lang::XInitialization*>(this);
+        return uno::Any(&p, rType);
+    }
     else if (rType == cppu::UnoType<lang::XTypeProvider>::get())
     {
         void* p = static_cast<lang::XTypeProvider*>(this);
@@ -619,6 +625,7 @@ uno::Sequence<uno::Type> SAL_CALL 
OCommonEmbeddedObject::getTypes()
         cppu::UnoType<container::XChild>::get(),
         cppu::UnoType<chart2::XDefaultSizeTransmitter>::get(),
         cppu::UnoType<lang::XServiceInfo>::get(),
+        cppu::UnoType<lang::XInitialization>::get(),
         cppu::UnoType<lang::XTypeProvider>::get(),
     };
     return aTypes;
@@ -629,4 +636,19 @@ uno::Sequence<sal_Int8> SAL_CALL 
OCommonEmbeddedObject::getImplementationId()
     return uno::Sequence<sal_Int8>();
 }
 
+void SAL_CALL OCommonEmbeddedObject::initialize(const uno::Sequence<uno::Any>& 
rArguments)
+{
+    if (!rArguments.hasElements())
+    {
+        return;
+    }
+
+    comphelper::SequenceAsHashMap aMap(rArguments[0]);
+    auto it = aMap.find("ReadOnly");
+    if (it != aMap.end())
+    {
+        it->second >>= m_bReadOnly;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/embeddedobj/source/commonembedding/persistence.cxx 
b/embeddedobj/source/commonembedding/persistence.cxx
index 3e4ab0dd989f..9618c2776de6 100644
--- a/embeddedobj/source/commonembedding/persistence.cxx
+++ b/embeddedobj/source/commonembedding/persistence.cxx
@@ -530,6 +530,11 @@ uno::Reference< util::XCloseable > 
OCommonEmbeddedObject::LoadDocumentFromStorag
         // set the document mode to embedded as the first step!!!
         EmbedAndReparentDoc_Impl( xDocument );
 
+        if (m_bReadOnly)
+        {
+            aLoadArgs.put("ReadOnly", true);
+        }
+
         if ( xDoc.is() )
         {
             xDoc->loadFromStorage( xSourceStorage, 
aLoadArgs.getPropertyValues() );
diff --git a/embeddedobj/source/inc/commonembobj.hxx 
b/embeddedobj/source/inc/commonembobj.hxx
index 922ecf50d59f..88fccb37bc40 100644
--- a/embeddedobj/source/inc/commonembobj.hxx
+++ b/embeddedobj/source/inc/commonembobj.hxx
@@ -34,6 +34,7 @@
 #include <com/sun/star/util/XCloseable.hpp>
 #include <com/sun/star/chart2/XDefaultSizeTransmitter.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
 #include <cppuhelper/weak.hxx>
 #include <rtl/ref.hxx>
 #include <map>
@@ -80,6 +81,7 @@ class OCommonEmbeddedObject : public 
css::embed::XEmbeddedObject
                             , public css::container::XChild
                             , public css::chart2::XDefaultSizeTransmitter
                             , public css::lang::XServiceInfo
+                            , public css::lang::XInitialization
                             , public css::lang::XTypeProvider
                             , public ::cppu::OWeakObject
 {
@@ -403,6 +405,9 @@ public:
     sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
     css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() 
override;
 
+    // XInitialization
+    void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& 
rArguments) override;
+
     // XTypeProvider
     css::uno::Sequence<css::uno::Type> SAL_CALL getTypes() override;
     css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx 
b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 0dbb7aaf0796..8d369fa50e40 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -25,6 +25,7 @@
 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
 #include <com/sun/star/chart2/XChartDocument.hpp>
 #include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
 
 #include <hintids.hxx>
 #include <sot/exchange.hxx>
@@ -98,6 +99,7 @@
 #include <svtools/embedhlp.hxx>
 #include <svx/postattr.hxx>
 #include <comphelper/lok.hxx>
+#include <comphelper/propertyvalue.hxx>
 #include <memory>
 
 using namespace sw::mark;
@@ -622,6 +624,14 @@ void SwWrtShell::LaunchOLEObj( long nVerb )
         if ( !pCli )
             pCli = new SwOleClient( &GetView(), &GetView().GetEditWin(), xRef 
);
 
+        uno::Reference<lang::XInitialization> xOLEInit(xRef.GetObject(), 
uno::UNO_QUERY);
+        if (xOLEInit.is())
+        {
+            uno::Sequence<beans::PropertyValue> aArguments
+                = { comphelper::makePropertyValue("ReadOnly", 
pCli->IsProtected()) };
+            xOLEInit->initialize({ uno::makeAny(aArguments) });
+        }
+
         static_cast<SwOleClient*>(pCli)->SetInDoVerb( true );
 
         CalcAndSetScale( xRef );
commit b8ee9d046028c0314cde5df3daffe2c20eb965a6
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Nov 25 14:53:04 2021 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Nov 26 13:29:19 2021 +0100

    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.
    
    (cherry picked from commit 4f9f1ac33366817df61c488a9f36b09c592ee939)
    
    Conflicts:
            sw/source/core/ole/ndole.cxx
    
    Change-Id: Ib3a8f2092d27dc1ebd3ef355c95a4a473988b163

diff --git a/include/sfx2/ipclient.hxx b/include/sfx2/ipclient.hxx
index 62c421c3c783..a7a85270c5e0 100644
--- a/include/sfx2/ipclient.hxx
+++ b/include/sfx2/ipclient.hxx
@@ -87,6 +87,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 12a8a2367a4b..09addf47f026 100644
--- a/include/svtools/embedhlp.hxx
+++ b/include/svtools/embedhlp.hxx
@@ -108,6 +108,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 5dc6267e5c94..d98ade7bd398 100644
--- a/sfx2/source/view/ipclient.cxx
+++ b/sfx2/source/view/ipclient.cxx
@@ -217,7 +217,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;
@@ -1040,6 +1040,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 f8dcf1356621..d71754238cea 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -135,9 +135,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();
 
@@ -239,6 +246,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),
@@ -394,6 +403,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 8382a42e58dc..e8c7506184f3 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 0a6b65a33897..fc77d0885d1e 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 1927872ed0d9..f6ca51279a29 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -54,6 +54,7 @@
 #include <atomic>
 #include <deque>
 #include <libxml/xmlwriter.h>
+#include <flyfrm.hxx>
 
 using namespace utl;
 using namespace com::sun::star::uno;
@@ -909,6 +910,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() )
@@ -942,6 +973,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 aeb522be5fc9..71033ee0af69 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 507919f601d7..001ea389f497 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -3245,8 +3245,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
@@ -3266,11 +3269,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 05f5f6ccc95a..4dc86bee5faf 100644
--- a/sw/source/uibase/uiview/swcli.cxx
+++ b/sw/source/uibase/uiview/swcli.cxx
@@ -29,6 +29,8 @@
 
 #include <toolkit/helper/vclunohelper.hxx>
 
+#include <ndole.hxx>
+
 using namespace com::sun::star;
 
 SwOleClient::SwOleClient(SwView *pView, SwEditWin *pWin, const 
svt::EmbeddedObjectRef& xObj)
@@ -164,4 +166,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: */

Reply via email to