sw/CppunitTest_sw_uibase_shells.mk              |    1 
 sw/inc/viewsh.hxx                               |    4 ++
 sw/qa/uibase/shells/data/ole-preview-update.odt |binary
 sw/qa/uibase/shells/shells.cxx                  |   23 +++++++++++++
 sw/source/core/view/viewsh.cxx                  |   41 ++++++++++++++++++++++++
 sw/source/uibase/shells/basesh.cxx              |    1 
 6 files changed, 70 insertions(+)

New commits:
commit e0eac6a1a74056c9222a9953ce0a95dcd9614bc7
Author:     Miklos Vajna <[email protected]>
AuthorDate: Thu Dec 2 17:08:41 2021 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Fri Dec 3 13:35:31 2021 +0100

    sw: update previews of OLE objects on "update all"
    
    Charts were already updated, it was not consistent that other embedded
    objects are not updated.
    
    This is especially useful if an ODT file is manipulated by a 3rd-party,
    then loaded into Writer just to update the previews of OLE objects.
    
    (cherry picked from commit 37892b97d00de29a86c735aaaff47c12e66e78ad)
    
    Conflicts:
            sw/qa/uibase/shells/shells.cxx
            sw/source/core/view/viewsh.cxx
            sw/source/uibase/shells/basesh.cxx
    
    Change-Id: If61aa037739c593abade933dcdd5474ad566b3e3

diff --git a/sw/CppunitTest_sw_uibase_shells.mk 
b/sw/CppunitTest_sw_uibase_shells.mk
index 9734b395bca6..a3b913ab572c 100644
--- a/sw/CppunitTest_sw_uibase_shells.mk
+++ b/sw/CppunitTest_sw_uibase_shells.mk
@@ -32,6 +32,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_uibase_shells, \
     unotest \
     utl \
     vcl \
+    tl \
 ))
 
 $(eval $(call gb_CppunitTest_use_externals,sw_uibase_shells,\
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index fe3fee74bcea..72b361203824 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -370,6 +370,10 @@ public:
     // All about fields.
     void UpdateFields(bool bCloseDB = false);
     bool IsAnyFieldInDoc() const;
+
+    /// Update the previews of all OLE objects.
+    void UpdateOleObjectPreviews();
+
     // Update all charts, for that exists any table.
     void UpdateAllCharts();
     bool HasCharts() const;
diff --git a/sw/qa/uibase/shells/data/ole-preview-update.odt 
b/sw/qa/uibase/shells/data/ole-preview-update.odt
new file mode 100644
index 000000000000..3fd4d264628e
Binary files /dev/null and b/sw/qa/uibase/shells/data/ole-preview-update.odt 
differ
diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx
index fbdf35758156..75f975fabaaa 100644
--- a/sw/qa/uibase/shells/shells.cxx
+++ b/sw/qa/uibase/shells/shells.cxx
@@ -17,6 +17,7 @@
 #include <editeng/adjustitem.hxx>
 #include <editeng/outlobj.hxx>
 #include <editeng/editobj.hxx>
+#include <unotools/ucbstreamhelper.hxx>
 
 #include <IDocumentContentOperations.hxx>
 #include <cmdid.h>
@@ -139,6 +140,28 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, 
testOleSavePreviewUpdate)
     CPPUNIT_ASSERT(xNameAccess->hasByName("ObjectReplacements/Object 2"));
 }
 
+CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testOlePreviewUpdate)
+{
+    // Given a document with an embedded Writer object:
+    load(DATA_DIRECTORY, "ole-preview-update.odt");
+
+    // When updating "all" (including OLE previews):
+    dispatchCommand(mxComponent, ".uno:UpdateAll", {});
+
+    // Then make sure the preview is no longer a 0-sized stream:
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    xStorable->storeToURL(maTempFile.GetURL(), {});
+    uno::Reference<packages::zip::XZipFileAccess2> xNameAccess
+        = 
packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory),
+                                                      maTempFile.GetURL());
+    uno::Reference<io::XInputStream> xInputStream(
+        xNameAccess->getByName("ObjectReplacements/Object 1"), uno::UNO_QUERY);
+    std::unique_ptr<SvStream> 
pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
+    // Without the accompanying fix in place, this test would have failed, the 
stream was still
+    // empty.
+    CPPUNIT_ASSERT_GREATER(static_cast<sal_uInt64>(0), 
pStream->remainingSize());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index c5d20fe38d88..e30fc909eaad 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -81,6 +81,9 @@
 #include <vcl/sysdata.hxx>
 #endif
 
+#include <frameformats.hxx>
+#include <fmtcntnt.hxx>
+
 bool SwViewShell::mbLstAct = false;
 ShellResource *SwViewShell::mpShellRes = nullptr;
 vcl::DeleteOnDeinit<std::shared_ptr<weld::Window>> 
SwViewShell::mpCareDialog(new std::shared_ptr<weld::Window>);
@@ -655,6 +658,44 @@ void SwViewShell::UpdateFields(bool bCloseDB)
         EndAction();
 }
 
+void SwViewShell::UpdateOleObjectPreviews()
+{
+    SwDoc* pDoc = GetDoc();
+    const SwFrameFormats* const pFormats = pDoc->GetSpzFrameFormats();
+    if (pFormats->empty())
+    {
+        return;
+    }
+
+    for (size_t i = 0; i < pFormats->size(); ++i)
+    {
+        SwFrameFormat* pFormat = (*pFormats)[i];
+        if (pFormat->Which() != RES_FLYFRMFMT)
+        {
+            continue;
+        }
+
+        const SwNodeIndex* pNodeIndex = pFormat->GetContent().GetContentIdx();
+        if (!pNodeIndex || !pNodeIndex->GetNodes().IsDocNodes())
+        {
+            continue;
+        }
+
+        SwNode* pNode = pDoc->GetNodes()[pNodeIndex->GetIndex() + 1];
+        SwOLENode* pOleNode = pNode->GetOLENode();
+        if (!pOleNode)
+        {
+            continue;
+        }
+
+        SwOLEObj& rOleObj = pOleNode->GetOLEObj();
+        svt::EmbeddedObjectRef& rObject = rOleObj.GetObject();
+        rObject.UpdateReplacement();
+        // Trigger the repaint.
+        pOleNode->SetChanged();
+    }
+}
+
 /** update all charts for which any table exists */
 void SwViewShell::UpdateAllCharts()
 {
diff --git a/sw/source/uibase/shells/basesh.cxx 
b/sw/source/uibase/shells/basesh.cxx
index 44d78d6e5821..892f4c8fdfbe 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -734,6 +734,7 @@ void SwBaseShell::Execute(SfxRequest &rReq)
                 rDis.Execute( FN_UPDATE_TOX );
                 rDis.Execute( FN_UPDATE_CHARTS );
                 rSh.CalcLayout();
+                rSh.UpdateOleObjectPreviews();
             }
             break;
 

Reply via email to