summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-02-17 18:00:24 +0100
committerMiklos Vajna <vmiklos@collabora.com>2022-02-18 13:36:02 +0100
commit503046607b96d4ee1b75034636021b1297853572 (patch)
treed70b65ad5939ed5ef7259ada1dc508ded58d51f9
parent197b5175ebb4b8fc610697188fc634ab28cc8d67 (diff)
svtools: fix lost replacement non-rendered graphic when updating it fails
This is similar to commit 8780fa41dcd164af244742461f4e57a4bcf4c7a4 (svtools: fix lost replacement grpahic when updating it via OLE fails, 2018-10-30), but that case was when we already had an old mpImpl->pGraphic, the updated failed and then we already lost the old one but didn't have a new one. Here what happened is that in case tools -> update -> update-all was used for an OLE object which had bad native data but a good preview, then the result was bad preview, depending on if you first scrolled to the OLE object to trigger rendering (good) or not (bad). The reason for this is that scrolling to the object calls GetGraphic(), which sets mpImpl->pGraphic using GetReplacement(bUpdate=false), which works, but svt::EmbeddedObjectRef::UpdateReplacement() calls GetReplacement(bUpdate=true). That explains why the update breaks the preview, but not when scrolling to it first. Fix the problem by improving svt::EmbeddedObjectRef::GetReplacement(): if getting an updated graphic fails, try to get a non-updated graphic. The result is that GetGraphic() after an UpdateReplacement() not only always return a non-nullptr Graphic, but also it's no longer of type None. (cherry picked from commit 24231f2a336c50eac5e6a1621c57e60ebe1e1cf4) Conflicts: sw/Module_sw.mk Change-Id: I8e5ff4aaaefdc58e032b325bb4001f2a604ccc8a
-rw-r--r--svtools/source/misc/embedhlp.cxx11
-rw-r--r--sw/CppunitTest_sw_core_view.mk71
-rw-r--r--sw/Module_sw.mk1
-rw-r--r--sw/qa/core/view/data/update-ole-object-previews.odtbin0 -> 10726 bytes
-rw-r--r--sw/qa/core/view/view.cxx71
5 files changed, 153 insertions, 1 deletions
diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
index d71754238cea..62fe453c0fd3 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -439,6 +439,15 @@ void EmbeddedObjectRef::GetReplacement( bool bUpdate )
}
std::unique_ptr<SvStream> pGraphicStream(GetGraphicStream( bUpdate ));
+ if (!pGraphicStream && aOldGraphic.IsNone())
+ {
+ // We have no old graphic, tried to get an updated one, but that failed. Try to get an old
+ // graphic instead of having no graphic at all.
+ pGraphicStream = GetGraphicStream(false);
+ SAL_WARN("svtools.misc",
+ "EmbeddedObjectRef::GetReplacement: failed to get updated graphic stream");
+ }
+
if ( pGraphicStream )
{
GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
@@ -455,7 +464,7 @@ void EmbeddedObjectRef::GetReplacement( bool bUpdate )
// failed. Go back to the old graphic instead of having no graphic at
// all.
mpImpl->pGraphic.reset(new Graphic(aOldGraphic));
- SAL_WARN("svtools.misc", "EmbeddedObjectRef::GetReplacement: update failed");
+ SAL_WARN("svtools.misc", "EmbeddedObjectRef::GetReplacement: failed to update graphic");
}
}
diff --git a/sw/CppunitTest_sw_core_view.mk b/sw/CppunitTest_sw_core_view.mk
new file mode 100644
index 000000000000..e8529467c10c
--- /dev/null
+++ b/sw/CppunitTest_sw_core_view.mk
@@ -0,0 +1,71 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# 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/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sw_core_view))
+
+$(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_view))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sw_core_view, \
+ sw/qa/core/view/view \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sw_core_view, \
+ cppu \
+ cppuhelper \
+ sal \
+ svl \
+ svt \
+ sw \
+ test \
+ unotest \
+ utl \
+ vcl \
+ sfx \
+ comphelper \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,sw_core_view,\
+ boost_headers \
+ libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sw_core_view,\
+ -I$(SRCDIR)/sw/inc \
+ -I$(SRCDIR)/sw/source/core/inc \
+ -I$(SRCDIR)/sw/source/uibase/inc \
+ -I$(SRCDIR)/sw/qa/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_api,sw_core_view,\
+ udkapi \
+ offapi \
+ oovbaapi \
+))
+
+$(eval $(call gb_CppunitTest_use_ure,sw_core_view))
+$(eval $(call gb_CppunitTest_use_vcl,sw_core_view))
+
+$(eval $(call gb_CppunitTest_use_rdb,sw_core_view,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sw_core_view,\
+ officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sw_core_view))
+
+$(eval $(call gb_CppunitTest_use_uiconfigs,sw_core_view, \
+ modules/swriter \
+))
+
+$(eval $(call gb_CppunitTest_use_more_fonts,sw_core_view))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index 723c26f53e40..50e7d11cd9d9 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -120,6 +120,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
CppunitTest_sw_core_unocore \
CppunitTest_sw_core_crsr \
CppunitTest_sw_uibase_uiview \
+ CppunitTest_sw_core_view \
))
ifneq ($(DISABLE_GUI),TRUE)
diff --git a/sw/qa/core/view/data/update-ole-object-previews.odt b/sw/qa/core/view/data/update-ole-object-previews.odt
new file mode 100644
index 000000000000..e6004afcb8ad
--- /dev/null
+++ b/sw/qa/core/view/data/update-ole-object-previews.odt
Binary files differ
diff --git a/sw/qa/core/view/view.cxx b/sw/qa/core/view/view.cxx
new file mode 100644
index 000000000000..7ba43a5001be
--- /dev/null
+++ b/sw/qa/core/view/view.cxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+#include <svtools/embedhlp.hxx>
+#include <vcl/graph.hxx>
+
+#include <doc.hxx>
+#include <docsh.hxx>
+#include <fmtcntnt.hxx>
+#include <frameformats.hxx>
+#include <frmfmt.hxx>
+#include <ndarr.hxx>
+#include <ndindex.hxx>
+#include <ndole.hxx>
+#include <node.hxx>
+#include <wrtsh.hxx>
+
+const OUStringLiteral DATA_DIRECTORY = "/sw/qa/core/view/data/";
+
+namespace
+{
+/// Covers sw/source/core/view/ fixes.
+class Test : public SwModelTestBase
+{
+};
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testUpdateOleObjectPreviews)
+{
+ // Given a document with two embedded objects, both with broken native data:
+ load(DATA_DIRECTORY, "update-ole-object-previews.odt");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ // When updating the previews of those embedded objects (right after document load, before
+ // painting the OLE objects):
+ pWrtShell->UpdateOleObjectPreviews();
+
+ // Then make sure that the working preview of those objects are not lost:
+ const SwFrameFormats* pFormats = pDoc->GetSpzFrameFormats();
+ CPPUNIT_ASSERT(pFormats);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pFormats->size());
+ for (size_t i = 0; i < pFormats->size(); ++i)
+ {
+ SwFrameFormat* pFormat = (*pFormats)[i];
+
+ const SwNodeIndex* pNodeIndex = pFormat->GetContent().GetContentIdx();
+ CPPUNIT_ASSERT(pNodeIndex);
+ SwNode* pNode = pDoc->GetNodes()[pNodeIndex->GetIndex() + 1];
+ SwOLENode* pOleNode = pNode->GetOLENode();
+ CPPUNIT_ASSERT(pOleNode);
+ SwOLEObj& rOleObj = pOleNode->GetOLEObj();
+ svt::EmbeddedObjectRef& rObject = rOleObj.GetObject();
+ // Without the accompanying fix in place, this test would have failed, the update broke the
+ // preview of the second embedded object.
+ CPPUNIT_ASSERT(!rObject.GetGraphic()->IsNone());
+ }
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */