comphelper/source/container/embeddedobjectcontainer.cxx |   13 -
 embeddedobj/Library_embobj.mk                           |    4 
 embeddedobj/source/commonembedding/embedobj.cxx         |    7 
 embeddedobj/source/commonembedding/miscobj.cxx          |  153 ++++++++++++++--
 embeddedobj/source/commonembedding/persistence.cxx      |   31 ---
 embeddedobj/source/inc/commonembobj.hxx                 |   20 ++
 embeddedobj/source/inc/strings.hrc                      |   19 +
 framework/source/services/autorecovery.cxx              |    2 
 include/comphelper/embeddedobjectcontainer.hxx          |    1 
 include/embeddedobj/embeddedupdate.hxx                  |   52 +++++
 include/embeddedobj/embobjdllapi.h                      |   20 ++
 include/svtools/embedhlp.hxx                            |    5 
 include/svtools/filechangedchecker.hxx                  |    6 
 include/unotools/mediadescriptor.hxx                    |    1 
 reportdesign/source/core/api/ReportDefinition.cxx       |    4 
 sfx2/source/doc/objstor.cxx                             |    7 
 svtools/source/misc/embedhlp.cxx                        |   13 +
 svtools/source/misc/filechangedchecker.cxx              |   22 +-
 sw/source/core/view/viewsh.cxx                          |    2 
 19 files changed, 329 insertions(+), 53 deletions(-)

New commits:
commit cf650ceaafb4d3a3f46991dc1b12efa0e37a71f9
Author:     Juergen Funk <juergen.funk...@cib.de>
AuthorDate: Tue Feb 22 09:19:29 2022 +0100
Commit:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
CommitDate: Tue May 10 09:02:01 2022 +0200

    tdf#147590 update OLE object after document refresh
    
    Regression from b099da78a6f0b3e120f706714003b05d84d11e70
    we didn't update linked OLE document after document reload
    
    Change-Id: I8e52f6430f454b276cb43449c6f7a3b0e07e909f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130692
    Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
    Tested-by: Jenkins

diff --git a/comphelper/source/container/embeddedobjectcontainer.cxx 
b/comphelper/source/container/embeddedobjectcontainer.cxx
index 2d85b73f44ba..094597fe6d06 100644
--- a/comphelper/source/container/embeddedobjectcontainer.cxx
+++ b/comphelper/source/container/embeddedobjectcontainer.cxx
@@ -1158,7 +1158,8 @@ namespace {
 
 }
 
-bool EmbeddedObjectContainer::StoreAsChildren(bool _bOasisFormat,bool 
_bCreateEmbedded,const uno::Reference < embed::XStorage >& _xStorage)
+bool EmbeddedObjectContainer::StoreAsChildren(bool _bOasisFormat,bool 
_bCreateEmbedded, bool _bAutoSaveEvent,
+                                              const uno::Reference < 
embed::XStorage >& _xStorage)
 {
     bool bResult = false;
     try
@@ -1222,7 +1223,7 @@ bool EmbeddedObjectContainer::StoreAsChildren(bool 
_bOasisFormat,bool _bCreateEm
                 uno::Reference< embed::XEmbedPersist > xPersist( xObj, 
uno::UNO_QUERY );
                 if ( xPersist.is() )
                 {
-                    uno::Sequence< beans::PropertyValue > aArgs( _bOasisFormat 
? 2 : 3 );
+                    uno::Sequence< beans::PropertyValue > aArgs( _bOasisFormat 
? 3 : 4 );
                     auto pArgs = aArgs.getArray();
                     pArgs[0].Name = "StoreVisualReplacement";
                     pArgs[0].Value <<= !_bOasisFormat;
@@ -1230,11 +1231,15 @@ bool EmbeddedObjectContainer::StoreAsChildren(bool 
_bOasisFormat,bool _bCreateEm
                     // if it is an embedded object or the optimized inserting 
fails the normal inserting should be done
                     pArgs[1].Name = "CanTryOptimization";
                     pArgs[1].Value <<= !_bCreateEmbedded;
+
+                    pArgs[2].Name = "AutoSaveEvent";
+                    pArgs[2].Value <<= _bAutoSaveEvent;
+
                     if ( !_bOasisFormat )
                     {
                         // if object has no cached replacement it will use 
this one
-                        pArgs[2].Name = "VisualReplacement";
-                        pArgs[2].Value <<= xStream;
+                        pArgs[3].Name = "VisualReplacement";
+                        pArgs[3].Value <<= xStream;
                     }
 
                     try
diff --git a/embeddedobj/Library_embobj.mk b/embeddedobj/Library_embobj.mk
index 35a654835dae..18cf55518d44 100644
--- a/embeddedobj/Library_embobj.mk
+++ b/embeddedobj/Library_embobj.mk
@@ -21,6 +21,10 @@ $(eval $(call gb_Library_set_include,embobj,\
        $$(INCLUDE) \
 ))
 
+$(eval $(call gb_Library_add_defs,embobj,\
+    -DEMBOBJ_DLLIMPLEMENTATION \
+))
+
 $(eval $(call gb_Library_use_external,embobj,boost_headers))
 
 $(eval $(call gb_Library_use_sdk_api,embobj))
diff --git a/embeddedobj/source/commonembedding/embedobj.cxx 
b/embeddedobj/source/commonembedding/embedobj.cxx
index 223f25e6302c..240112b2483e 100644
--- a/embeddedobj/source/commonembedding/embedobj.cxx
+++ b/embeddedobj/source/commonembedding/embedobj.cxx
@@ -639,6 +639,13 @@ void SAL_CALL OCommonEmbeddedObject::setContainerName( 
const OUString& sName )
     m_aContainerName = sName;
 }
 
+void OCommonEmbeddedObject::SetOleState(bool bIsOleUpdate)
+{
+    ::osl::MutexGuard aGuard( m_aMutex );
+
+    m_bOleUpdate = bIsOleUpdate;
+}
+
 css::uno::Reference< css::uno::XInterface > SAL_CALL 
OCommonEmbeddedObject::getParent()
 {
     return m_xParent;
diff --git a/embeddedobj/source/commonembedding/miscobj.cxx 
b/embeddedobj/source/commonembedding/miscobj.cxx
index a5d5573416d1..f41d35957b5d 100644
--- a/embeddedobj/source/commonembedding/miscobj.cxx
+++ b/embeddedobj/source/commonembedding/miscobj.cxx
@@ -35,6 +35,13 @@
 #include <cppuhelper/queryinterface.hxx>
 #include <comphelper/mimeconfighelper.hxx>
 
+#include <vcl/weld.hxx>
+#include <unotools/resmgr.hxx>
+#include <vcl/stdtext.hxx>
+#include <strings.hrc>
+#include <osl/file.hxx>
+#include <comphelper/DirectoryHelper.hxx>
+
 #include <vcl/svapp.hxx>
 #include <tools/diagnose_ex.h>
 #include <cppuhelper/supportsservice.hxx>
@@ -62,7 +69,11 @@ OCommonEmbeddedObject::OCommonEmbeddedObject( const 
uno::Reference< uno::XCompon
 , m_bWaitSaveCompleted( false )
 , m_bIsLinkURL( false )
 , m_bLinkTempFileChanged( false )
+, m_pLinkFile( )
+, m_bOleUpdate( false )
+, m_bInHndFunc( false )
 , m_bLinkHasPassword( false )
+, m_aLinkTempFile( )
 , m_bHasClonedSize( false )
 , m_nClonedMapUnit( 0 )
 {
@@ -88,7 +99,11 @@ OCommonEmbeddedObject::OCommonEmbeddedObject(
 , m_bWaitSaveCompleted( false )
 , m_bIsLinkURL( true )
 , m_bLinkTempFileChanged( false )
+, m_pLinkFile( )
+, m_bOleUpdate( false )
+, m_bInHndFunc( false )
 , m_bLinkHasPassword( false )
+, m_aLinkTempFile( )
 , m_bHasClonedSize( false )
 , m_nClonedMapUnit( 0 )
 {
@@ -224,26 +239,13 @@ void OCommonEmbeddedObject::LinkInit_Impl(
         // task-ID above)
         //
         // open OLE original data as read input file
-        uno::Reference< ucb::XSimpleFileAccess3 > xTempAccess( 
ucb::SimpleFileAccess::create( m_xContext ) );
-        uno::Reference< io::XInputStream > xInStream( 
xTempAccess->openFileRead( m_aLinkURL ) );
-
-        if(xInStream.is())
+        if ( comphelper::DirectoryHelper::fileExists( m_aLinkURL ) )
         {
             // create temporary file
-            m_aLinkTempFile = io::TempFile::create(m_xContext);
-            uno::Reference< ucb::XSimpleFileAccess > 
xTempOutAccess(ucb::SimpleFileAccess::create(m_xContext));
-            // if the temp stream is used, then the temp file remains locked
-            uno::Reference< io::XOutputStream > 
xOutStream(xTempOutAccess->openFileWrite(m_aLinkTempFile->getUri()));
-
-            if(m_aLinkTempFile.is())
-            {
-                // completely copy content of original OLE data
-                ::comphelper::OStorageHelper::CopyInputToOutput(xInStream, 
xOutStream);
+            m_aLinkTempFile = io::TempFile::create( m_xContext );
 
-                // reset flag m_bLinkTempFileChanged, so it will also work for 
multiple
-                // save op's of the containing file/document
-                m_bLinkTempFileChanged = false;
-            }
+            m_pLinkFile.reset( new FileChangedChecker( m_aLinkURL ) );
+            handleLinkedOLE( CopyBackToOLELink::CopyLinkToTempInit );
         }
     }
 
@@ -379,6 +381,123 @@ void OCommonEmbeddedObject::PostEvent_Impl( const 
OUString& aEventName )
 }
 
 
+static int ShowMsgDialog( TranslateId Msg, const OUString& sFileName )
+{
+    std::locale aResLocale = Translate::Create( "emo" );
+    OUString aMsg  = Translate::get( Msg, aResLocale );
+    OUString aBtn  = Translate::get( BTN_OVERWRITE_TEXT, aResLocale );
+    OUString aTemp = sFileName;
+
+    osl::FileBase::getSystemPathFromFileURL( sFileName, aTemp );
+
+    aMsg = aMsg.replaceFirst( "%{filename}", aTemp );
+    weld::Window* pParent = Application::GetFrameWeld( nullptr );
+
+    std::unique_ptr<weld::MessageDialog> xQueryBox 
(Application::CreateMessageDialog( pParent,
+        VclMessageType::Warning, VclButtonsType::NONE, aMsg ) );
+    xQueryBox->add_button( aBtn, RET_YES );
+    xQueryBox->add_button( GetStandardText( StandardButtonType::Cancel ), 
RET_CANCEL );
+    xQueryBox->set_default_response( RET_CANCEL );
+
+    return xQueryBox->run();
+}
+
+
+void OCommonEmbeddedObject::handleLinkedOLE( CopyBackToOLELink eState )
+{
+    // do not refresh and autosave at the same time
+    // when refresh all, then get both Link and Ole Update, in this case 
ignore OLE-refresh
+    if ( m_bInHndFunc || m_bOleUpdate || !m_aLinkTempFile.is() )
+        return;
+
+    m_bInHndFunc = true;
+
+    bool bLnkFileChg = m_pLinkFile->hasFileChanged( false );
+    bool bTmpFileChg = m_bLinkTempFileChanged;
+
+
+    if ( eState != CopyBackToOLELink::CopyLinkToTempInit && !bLnkFileChg && 
!bTmpFileChg )
+    {
+        // no changes
+        eState = CopyBackToOLELink::NoCopy;
+    }
+    else if ( ( eState == CopyBackToOLELink::CopyTempToLink ) && bLnkFileChg 
&& !bTmpFileChg )
+    {
+        // Save pressed,  but the Link-file is changed, but not the temp-file
+        // in this case update the object with new link data
+        eState = CopyBackToOLELink::CopyLinkToTempRefresh;
+    }
+    else if ( ( eState == CopyBackToOLELink::CopyTempToLink ) && bLnkFileChg 
&& bTmpFileChg )
+    {
+        // Save pressed,  but the Link-file is changed, question to user for 
overwrite
+        if ( ShowMsgDialog(STR_OVERWRITE_LINK, m_aLinkURL) == RET_CANCEL )
+            eState = CopyBackToOLELink::NoCopy;
+    }
+    else if ( ( eState == CopyBackToOLELink::CopyLinkToTemp ) && bTmpFileChg )
+    {
+        // Refresh pressed,  but the Temp-file is changed, question to user 
for overwrite
+        // it is not importent it has bLnkFileChg, always overwite the 
temp-file
+        if ( ShowMsgDialog( STR_OVERWRITE_TEMP, m_aLinkURL ) == RET_CANCEL )
+            eState = CopyBackToOLELink::NoCopy;
+    }
+
+    auto writeFile = [ this ]( const OUString& SrcName, const OUString& 
DesName )
+    {
+        uno::Reference < ucb::XSimpleFileAccess2 > xWriteAccess( 
ucb::SimpleFileAccess::create( m_xContext ) );
+        uno::Reference < ucb::XSimpleFileAccess > xReadAccess( 
ucb::SimpleFileAccess::create( m_xContext ) );
+
+        try
+        {
+            uno::Reference < io::XInputStream > xInStream( 
xReadAccess->openFileRead (SrcName ) );
+
+            // This is *needed* since OTempFileService calls 
OTempFileService::readBytes which
+            // ensures the SvStream mpStream gets/is opened, *but* also sets 
the mnCachedPos from
+            // OTempFileService which still points to the end-of-file (from 
write-cc'ing).
+            uno::Reference < io::XSeekable > xSeek( xInStream, 
uno::UNO_QUERY_THROW );
+            xSeek->seek( 0 );
+
+            xWriteAccess->writeFile( DesName, xInStream );
+            m_bLinkTempFileChanged = false;
+            // store the new timestamp
+            m_pLinkFile->hasFileChanged();
+        }
+        catch ( const uno::Exception& ex )
+        {
+            OUString aMsg;
+            osl::FileBase::getSystemPathFromFileURL( SrcName, aMsg );
+            aMsg = ex.Message + "\n\n" + aMsg;
+            weld::Window* pParent = Application::GetFrameWeld( nullptr );
+            std::unique_ptr<weld::MessageDialog> xQueryBox( 
Application::CreateMessageDialog( pParent,
+                                                     VclMessageType::Error, 
VclButtonsType::Ok, aMsg ) );
+
+            xQueryBox->run();
+        }
+    };
+
+    switch ( eState )
+    {
+        case CopyBackToOLELink::NoCopy:
+            break;
+        case CopyBackToOLELink::CopyLinkToTemp: // copy Link-File to Temp-File 
  (Refresh)
+        case CopyBackToOLELink::CopyLinkToTempInit: //create temp file
+            writeFile( m_aLinkURL, m_aLinkTempFile->getUri() );
+            break;
+        case CopyBackToOLELink::CopyTempToLink: // copy Temp-File to Link-File 
  (Save)
+            // tdf#141529 if we have a changed copy of the original OLE data 
we now
+            // need to write it back 'over' the original OLE data
+            writeFile( m_aLinkTempFile->getUri(), m_aLinkURL );
+            break;
+        case CopyBackToOLELink::CopyLinkToTempRefresh: // need a Refresh not 
save
+            // do nothing
+            break;
+        default:
+            break;
+    }
+
+    m_bInHndFunc = false;
+}
+
+
 uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( const uno::Type& 
rType )
 {
     uno::Any aReturn;
diff --git a/embeddedobj/source/commonembedding/persistence.cxx 
b/embeddedobj/source/commonembedding/persistence.cxx
index 77bc947650af..b32d07f1c59c 100644
--- a/embeddedobj/source/commonembedding/persistence.cxx
+++ b/embeddedobj/source/commonembedding/persistence.cxx
@@ -54,6 +54,7 @@
 #include <comphelper/mimeconfighelper.hxx>
 #include <comphelper/namedvaluecollection.hxx>
 #include <comphelper/propertyvalue.hxx>
+#include <unotools/mediadescriptor.hxx>
 
 #include <tools/diagnose_ex.h>
 #include <sal/log.hxx>
@@ -392,6 +393,8 @@ uno::Reference< util::XCloseable > 
OCommonEmbeddedObject::LoadLink_Impl()
 
     try
     {
+        handleLinkedOLE(CopyBackToOLELink::CopyLinkToTemp);
+
         // the document is not really an embedded one, it is a link
         EmbedAndReparentDoc_Impl( xDocument );
 
@@ -1254,12 +1257,14 @@ void SAL_CALL OCommonEmbeddedObject::storeAsEntry( 
const uno::Reference< embed::
                             const uno::Sequence< beans::PropertyValue >& 
lArguments,
                             const uno::Sequence< beans::PropertyValue >& 
lObjArgs )
 {
-    // TODO: use lObjArgs
-
     ::osl::ResettableMutexGuard aGuard( m_aMutex );
     if ( m_bDisposed )
         throw lang::DisposedException(); // TODO
 
+    bool AutoSaveEvent = false;
+    utl::MediaDescriptor lArgs(lObjArgs);
+    lArgs[utl::MediaDescriptor::PROP_AUTOSAVEEVENT] >>= AutoSaveEvent;
+
     if ( m_nObjectState == -1 )
     {
         // the object is still not loaded
@@ -1279,26 +1284,8 @@ void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const 
uno::Reference< embed::
     {
         m_aNewEntryName = sEntName;
 
-        if(m_aLinkTempFile.is() && m_bLinkTempFileChanged)
-        {
-            // tdf#141529 if we have a changed copy of the original OLE data 
we now
-            // need to write it back 'over' the original OLE data
-            uno::Reference < ucb::XSimpleFileAccess2 > 
xFileAccess(ucb::SimpleFileAccess::create( m_xContext ));
-
-            uno::Reference< ucb::XSimpleFileAccess > 
xTempAccess(ucb::SimpleFileAccess::create(m_xContext));
-            // if the temp stream is used, then the temp file remains locked
-            uno::Reference< io::XInputStream > 
xInStream(xTempAccess->openFileRead(m_aLinkTempFile->getUri()));
-            // This is *needed* since OTempFileService calls 
OTempFileService::readBytes which
-            // ensures the SvStream mpStream gets/is opened, *but* also sets 
the mnCachedPos from
-            // OTempFileService which still points to the end-of-file (from 
write-cc'ing).
-            uno::Reference < io::XSeekable > xSeek( xInStream, 
uno::UNO_QUERY_THROW );
-            xSeek->seek(0);
-
-            xFileAccess->writeFile(m_aLinkURL, xInStream);
-
-            // reset flag m_bLinkTempFileChanged
-            m_bLinkTempFileChanged = false;
-        }
+        if ( !AutoSaveEvent )
+            handleLinkedOLE(CopyBackToOLELink::CopyTempToLink);
 
         return;
     }
diff --git a/embeddedobj/source/inc/commonembobj.hxx 
b/embeddedobj/source/inc/commonembobj.hxx
index 785a28eaf0fd..61abe0299ee1 100644
--- a/embeddedobj/source/inc/commonembobj.hxx
+++ b/embeddedobj/source/inc/commonembobj.hxx
@@ -36,9 +36,11 @@
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/lang/XInitialization.hpp>
 #include <cppuhelper/weak.hxx>
+#include <embeddedobj/embeddedupdate.hxx>
 #include <rtl/ref.hxx>
 #include <map>
 #include <memory>
+#include <svtools/filechangedchecker.hxx>
 
 namespace com::sun::star {
     namespace embed {
@@ -76,6 +78,7 @@ class Interceptor;
  * document model successfully.
  */
 class OCommonEmbeddedObject : public css::embed::XEmbeddedObject
+                            , public css::embed::EmbeddedUpdate
                             , public css::embed::XEmbedPersist2
                             , public css::embed::XLinkageSupport
                             , public css::embed::XInplaceObject
@@ -141,6 +144,9 @@ protected:
 
     bool m_bIsLinkURL;
     bool m_bLinkTempFileChanged;
+    ::std::unique_ptr< FileChangedChecker > m_pLinkFile;
+    bool m_bOleUpdate;
+    bool m_bInHndFunc;
 
     // embedded object related stuff
     OUString m_aEntryName;
@@ -193,6 +199,16 @@ private:
 
     void Deactivate();
 
+    // when State = CopyTempToLink        -> the user pressed the save button
+    //                                       when change in embedded part then 
copy to the linked-file
+    //              CopyLinkToTemp        -> the user pressed the refresh 
button
+    //                                       when change in linked-file then 
copy to the embedded part (temp-file)
+    //              CopyLinkToTempInit    -> create the temp file
+    //              CopyLinkToTempRefresh -> when save and Link change but not 
temp then update temp
+    enum class CopyBackToOLELink {NoCopy, CopyTempToLink, CopyLinkToTemp, 
CopyLinkToTempInit, CopyLinkToTempRefresh};
+
+    void handleLinkedOLE( CopyBackToOLELink eState );
+
     void StateChangeNotification_Impl( bool bBeforeChange, sal_Int32 
nOldState, sal_Int32 nNewState,::osl::ResettableMutexGuard& _rGuard );
 
     void SwitchStateTo_Impl( sal_Int32 nNextState );
@@ -294,6 +310,10 @@ public:
 
     virtual void SAL_CALL setContainerName( const OUString& sName ) override;
 
+// EmbeddedUpdate
+
+    virtual void SetOleState(bool bIsOleUpdate) override;
+
 
 // XVisualObject
 
diff --git a/embeddedobj/source/inc/strings.hrc 
b/embeddedobj/source/inc/strings.hrc
new file mode 100644
index 000000000000..a3b323c54cf3
--- /dev/null
+++ b/embeddedobj/source/inc/strings.hrc
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#pragma once
+
+#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const 
*>(u8##String))
+
+#define BTN_OVERWRITE_TEXT           NC_("BTN_OVERWRITE_TEXT", "Overwrite")
+#define STR_OVERWRITE_LINK           NC_("STR_OVERWRITE_LINK", "You have made 
changes to the %{filename}, saving will overwrite the data from the inserted 
object.\n\nDo you still want to overwrite this data?")
+#define STR_OVERWRITE_TEMP           NC_("STR_OVERWRITE_TEMP", "You have 
changed the data in the inserted object which will be overwritten by updating 
the %{filename}.\n\nDo you still want to overwrite this data?")
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/framework/source/services/autorecovery.cxx 
b/framework/source/services/autorecovery.cxx
index 86715bda0057..e3321773256f 100644
--- a/framework/source/services/autorecovery.cxx
+++ b/framework/source/services/autorecovery.cxx
@@ -3008,6 +3008,8 @@ void AutoRecovery::implts_saveOneDoc(const OUString&
     // for make hyperlinks working
     lNewArgs[utl::MediaDescriptor::PROP_DOCUMENTBASEURL] <<= OUString();
 
+    lNewArgs[utl::MediaDescriptor::PROP_AUTOSAVEEVENT] <<= true;
+
     // try to save this document as a new temp file every time.
     // Mark AutoSave state as "INCOMPLETE" if it failed.
     // Because the last temp file is too old and does not include all changes.
diff --git a/include/comphelper/embeddedobjectcontainer.hxx 
b/include/comphelper/embeddedobjectcontainer.hxx
index c477a6fbe8c2..cc040da152c3 100644
--- a/include/comphelper/embeddedobjectcontainer.hxx
+++ b/include/comphelper/embeddedobjectcontainer.hxx
@@ -166,6 +166,7 @@ public:
     bool            StoreChildren(bool _bOasisFormat,bool _bObjectsOnly);
     bool            StoreAsChildren( bool _bOasisFormat
                                         ,bool _bCreateEmbedded
+                                        ,bool _bAutoSaveEvent
                                         ,const css::uno::Reference < 
css::embed::XStorage >& _xStorage);
 
     static css::uno::Reference< css::io::XInputStream > 
GetGraphicReplacementStream(
diff --git a/include/embeddedobj/embeddedupdate.hxx 
b/include/embeddedobj/embeddedupdate.hxx
new file mode 100644
index 000000000000..1db3f36d61dc
--- /dev/null
+++ b/include/embeddedobj/embeddedupdate.hxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#pragma once
+
+#include <embeddedobj/embobjdllapi.h>
+
+namespace com
+{
+namespace sun
+{
+namespace star
+{
+namespace embed
+{
+/** This class is only used to tell the OCommonEmbeddedObject class
+    that the following call is an Link- / Ole-refresh.
+
+    @since LibreOffice 7.4
+ */
+class EMBOBJ_DLLPUBLIC EmbeddedUpdate
+{
+    /** By "Refresh all" is used to perform an OLE update and a link update.
+        In the case of a link update, the class OCommonEmbeddedObject is
+        informed with true that a link update will take place next
+
+        @param bIsOleUpdate
+            what kind of update, when true  is OLE-Object
+                                 when false is Link-Object
+     */
+public:
+    virtual void SetOleState(bool bIsOleUpdate) = 0;
+
+    EmbeddedUpdate() = default;
+    virtual ~EmbeddedUpdate() = default;
+
+private:
+    EmbeddedUpdate(const EmbeddedUpdate&) = delete;
+    EmbeddedUpdate& operator=(const EmbeddedUpdate&) = delete;
+};
+};
+};
+};
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/include/embeddedobj/embobjdllapi.h 
b/include/embeddedobj/embobjdllapi.h
new file mode 100644
index 000000000000..36aa54217fb9
--- /dev/null
+++ b/include/embeddedobj/embobjdllapi.h
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#pragma once
+
+#include <sal/types.h>
+
+#if defined(EMBOBJ_DLLIMPLEMENTATION)
+#define EMBOBJ_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define EMBOBJ_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/include/svtools/embedhlp.hxx b/include/svtools/embedhlp.hxx
index 9d4cb8e85c39..4930e5b7630b 100644
--- a/include/svtools/embedhlp.hxx
+++ b/include/svtools/embedhlp.hxx
@@ -49,6 +49,7 @@ class SVT_DLLPUBLIC EmbeddedObjectRef
 
     SVT_DLLPRIVATE std::unique_ptr<SvStream> GetGraphicStream( bool bUpdate ) 
const;
     SVT_DLLPRIVATE void GetReplacement( bool bUpdate );
+    SVT_DLLPRIVATE void UpdateOleObject( bool bUpdateOle);
 
     EmbeddedObjectRef& operator = ( const EmbeddedObjectRef& ) = delete;
 
@@ -101,7 +102,9 @@ public:
                         const css::uno::Reference< css::io::XInputStream >& 
xInGrStream,
                         const OUString& rMediaType );
 
-    void            UpdateReplacement();
+                    // bUpdateOle = false udate the Link-Objects
+                    //            = true  update the OLE-Objects
+    void            UpdateReplacement( bool bUpdateOle = false );
     void            UpdateReplacementOnDemand();
     void Lock( bool bLock = true );
     void            Clear();
diff --git a/include/svtools/filechangedchecker.hxx 
b/include/svtools/filechangedchecker.hxx
index d63d146688c6..9800654678fa 100644
--- a/include/svtools/filechangedchecker.hxx
+++ b/include/svtools/filechangedchecker.hxx
@@ -35,7 +35,11 @@ private:
 
 public:
     void resetTimer();
-    bool hasFileChanged();
+    // bUpdate = true  when file has changed, get the return and the object 
get the new time
+    //         = false when file has changed, only get the return, not change 
the object
+    bool hasFileChanged(bool bUpdate = true);
     FileChangedChecker(const OUString& rFilename,
             const ::std::function<void ()>& rCallback);
+    // with out Timer function
+    FileChangedChecker(const OUString& rFilename);
 };
diff --git a/include/unotools/mediadescriptor.hxx 
b/include/unotools/mediadescriptor.hxx
index 1e4b3c064d1c..92728fa51972 100644
--- a/include/unotools/mediadescriptor.hxx
+++ b/include/unotools/mediadescriptor.hxx
@@ -101,6 +101,7 @@ class UNOTOOLS_DLLPUBLIC MediaDescriptor : public 
comphelper::SequenceAsHashMap
         static constexpr OUStringLiteral PROP_VIEWONLY = u"ViewOnly";
         static constexpr OUStringLiteral PROP_DOCUMENTBASEURL = 
u"DocumentBaseURL";
         static constexpr OUStringLiteral PROP_SUGGESTEDSAVEASNAME = 
u"SuggestedSaveAsName";
+        static constexpr OUStringLiteral PROP_AUTOSAVEEVENT = u"AutoSaveEvent";
 
     // interface
     public:
diff --git a/reportdesign/source/core/api/ReportDefinition.cxx 
b/reportdesign/source/core/api/ReportDefinition.cxx
index 638b7a87a631..e9f5393a5e7c 100644
--- a/reportdesign/source/core/api/ReportDefinition.cxx
+++ b/reportdesign/source/core/api/ReportDefinition.cxx
@@ -1291,6 +1291,8 @@ void SAL_CALL OReportDefinition::storeToStorage( const 
uno::Reference< embed::XS
     uno::Sequence< uno::Any > aDelegatorArguments;
     utl::MediaDescriptor aDescriptor( _aMediaDescriptor );
     lcl_extractAndStartStatusIndicator( aDescriptor, xStatusIndicator, 
aDelegatorArguments );
+    bool AutoSaveEvent = false;
+    aDescriptor[utl::MediaDescriptor::PROP_AUTOSAVEEVENT] >>= AutoSaveEvent;
 
     // properties
     uno::Sequence < beans::PropertyValue > aProps;
@@ -1382,7 +1384,7 @@ void SAL_CALL OReportDefinition::storeToStorage( const 
uno::Reference< embed::XS
         if ( _xStorageToSaveTo == m_pImpl->m_xStorage )
             bPersist = m_pImpl->m_pObjectContainer->StoreChildren(true,false);
         else
-            bPersist = 
m_pImpl->m_pObjectContainer->StoreAsChildren(true,true,_xStorageToSaveTo);
+            bPersist = 
m_pImpl->m_pObjectContainer->StoreAsChildren(true,true,AutoSaveEvent,_xStorageToSaveTo);
 
         if( bPersist )
             
m_pImpl->m_pObjectContainer->SetPersistentEntries(m_pImpl->m_xStorage);
diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx
index fec08d32a0ba..288b6a7ae6a9 100644
--- a/sfx2/source/doc/objstor.cxx
+++ b/sfx2/source/doc/objstor.cxx
@@ -76,6 +76,7 @@
 #include <unotools/ucbhelper.hxx>
 #include <unotools/tempfile.hxx>
 #include <unotools/docinfohelper.hxx>
+#include <unotools/mediadescriptor.hxx>
 #include <ucbhelper/content.hxx>
 #include <sot/storage.hxx>
 #include <sot/exchange.hxx>
@@ -3242,10 +3243,14 @@ bool SfxObjectShell::SaveAsChildren( SfxMedium& rMedium 
)
         return true;
     }
 
+    bool AutoSaveEvent = false;
+    utl::MediaDescriptor lArgs(rMedium.GetArgs());
+    lArgs[utl::MediaDescriptor::PROP_AUTOSAVEEVENT] >>= AutoSaveEvent;
+
     if ( pImpl->mxObjectContainer )
     {
         bool bOasis = ( SotStorage::GetVersion( xStorage ) > 
SOFFICE_FILEFORMAT_60 );
-        
GetEmbeddedObjectContainer().StoreAsChildren(bOasis,SfxObjectCreateMode::EMBEDDED
 == eCreateMode,xStorage);
+        
GetEmbeddedObjectContainer().StoreAsChildren(bOasis,SfxObjectCreateMode::EMBEDDED
 == eCreateMode,AutoSaveEvent,xStorage);
     }
 
     uno::Sequence<OUString> aExceptions;
diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
index 29e427799c82..809a2b155790 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -51,6 +51,7 @@
 #include <com/sun/star/embed/XStateChangeListener.hpp>
 #include <com/sun/star/embed/XLinkageSupport.hpp>
 #include <com/sun/star/chart2/XDefaultSizeTransmitter.hpp>
+#include <embeddedobj/embeddedupdate.hxx>
 #include <cppuhelper/implbase.hxx>
 #include <vcl/svapp.hxx>
 #include <tools/diagnose_ex.h>
@@ -878,7 +879,7 @@ bool EmbeddedObjectRef::IsChart(const css::uno::Reference < 
css::embed::XEmbedde
         || SvGlobalName(SO3_SCH_CLASSID_60) == aObjClsId;
 }
 
-void EmbeddedObjectRef::UpdateReplacement()
+void EmbeddedObjectRef::UpdateReplacement( bool bUpdateOle )
 {
     if (mpImpl->bUpdating)
     {
@@ -886,10 +887,20 @@ void EmbeddedObjectRef::UpdateReplacement()
         return;
     }
     mpImpl->bUpdating = true;
+    UpdateOleObject( bUpdateOle );
     GetReplacement(true);
+    UpdateOleObject( false );
     mpImpl->bUpdating = false;
 }
 
+void EmbeddedObjectRef::UpdateOleObject( bool bUpdateOle )
+{
+    embed::EmbeddedUpdate* pObj = dynamic_cast<embed::EmbeddedUpdate*> 
(GetObject().get());
+    if( pObj )
+        pObj->SetOleState( bUpdateOle );
+}
+
+
 void EmbeddedObjectRef::UpdateReplacementOnDemand()
 {
     mpImpl->pGraphic.reset();
diff --git a/svtools/source/misc/filechangedchecker.cxx 
b/svtools/source/misc/filechangedchecker.cxx
index 8536eb0bda57..dd7cf22b924c 100644
--- a/svtools/source/misc/filechangedchecker.cxx
+++ b/svtools/source/misc/filechangedchecker.cxx
@@ -21,7 +21,7 @@ FileChangedChecker::FileChangedChecker(const OUString& 
rFilename,
     , mLastModTime()
     , mpCallback(rCallback)
 {
-    // Get the curren last file modified Status
+    // Get the current last file modified Status
     getCurrentModTime(mLastModTime);
 
     // associate the callback function for the Timer
@@ -34,10 +34,23 @@ FileChangedChecker::FileChangedChecker(const OUString& 
rFilename,
     resetTimer();
 }
 
+FileChangedChecker::FileChangedChecker(const OUString& rFilename)
+    : mTimer("")
+    , mFileName(rFilename)
+    , mLastModTime()
+    , mpCallback(nullptr)
+{
+    // Get the current last file modified Status
+    getCurrentModTime(mLastModTime);
+}
+
 void FileChangedChecker::resetTimer()
 {
+    if (mpCallback == nullptr)
+        return;
+
     // Start the Idle if it's not active
-    if(!mTimer.IsActive())
+    if (!mTimer.IsActive())
         mTimer.Start();
 
     // Set lowest Priority
@@ -61,7 +74,7 @@ bool FileChangedChecker::getCurrentModTime(TimeValue& 
o_rValue) const
     return true;
 }
 
-bool FileChangedChecker::hasFileChanged()
+bool FileChangedChecker::hasFileChanged(bool bUpdate)
 {
     // Get the current file Status
     TimeValue newTime={0,0};
@@ -75,7 +88,8 @@ bool FileChangedChecker::hasFileChanged()
     {
         // Since the file has changed, set the new status as the file status 
and
         // return True
-        mLastModTime = newTime ;
+        if(bUpdate)
+            mLastModTime = newTime ;
 
         return true;
     }
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index b2415419eb5e..3358043a2b8d 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -757,7 +757,7 @@ void SwViewShell::UpdateOleObjectPreviews()
 
         SwOLEObj& rOleObj = pOleNode->GetOLEObj();
         svt::EmbeddedObjectRef& rObject = rOleObj.GetObject();
-        rObject.UpdateReplacement();
+        rObject.UpdateReplacement( true );
         // Trigger the repaint.
         pOleNode->SetChanged();
     }

Reply via email to