diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-10-13 17:00:30 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2021-10-13 18:13:39 +0200 |
commit | a399b05401fc35ebba4dbd07504fae4a609b3614 (patch) | |
tree | d26da47d35f0eaaefb9ac762c38a818a4434fd9e | |
parent | 03c474c640d63f54d520712693e2f47976d8d531 (diff) |
sw: fix corrupted proxy object for SwGrfNode via the view cursor UNO API
Creating an SwXTextFrame for a graphic node will result in a wrapper
that has no underlying SwTextNode, as the downcast from SwNode fails in
SwXParagraphEnumerationImpl::NextElement_Impl(). This is certainly not
intended, similar code in SwFmDrawPage::CreateShape() handles the text
node, graphic node and OLE node cases separately.
To make this more problematic, this corrupted wrapper can be still alive
by the time we try to save to ODT, but the wrapper without an underlying
SwTextNode will be unable to enumerat the paragraphs of the text frame,
so it throws, making it impossible to save the document.
Fix this by limiting the TextFrame property of the cursor to actual text
frames any returning an empty reference in other cases.
If there is a need to access graphic or OLE frames via that API, then
dedicated properties can be added to expose those different nodes.
Change-Id: I5e97a826271b0d8a1bf262e43cd8516656b37c3a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123560
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/core/unocore/data/graphic.png | bin | 0 -> 766 bytes | |||
-rw-r--r-- | sw/qa/core/unocore/unocore.cxx | 26 | ||||
-rw-r--r-- | sw/source/core/unocore/unocrsrhelper.cxx | 3 |
3 files changed, 28 insertions, 1 deletions
diff --git a/sw/qa/core/unocore/data/graphic.png b/sw/qa/core/unocore/data/graphic.png Binary files differnew file mode 100644 index 000000000000..fdad35484e7c --- /dev/null +++ b/sw/qa/core/unocore/data/graphic.png diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx index 36007fc7cd26..520c1e21ea28 100644 --- a/sw/qa/core/unocore/unocore.cxx +++ b/sw/qa/core/unocore/unocore.cxx @@ -12,6 +12,7 @@ #include <com/sun/star/text/BibliographyDataType.hpp> #include <com/sun/star/text/XTextAppend.hpp> #include <com/sun/star/text/XTextFrame.hpp> +#include <com/sun/star/text/XTextViewCursorSupplier.hpp> #include <comphelper/propertyvalue.hxx> #include <comphelper/sequenceashashmap.hxx> @@ -20,6 +21,7 @@ #include <unotextrange.hxx> #include <unotxdoc.hxx> #include <docsh.hxx> +#include <view.hxx> using namespace ::com::sun::star; @@ -158,6 +160,30 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testLinkedStyles) CPPUNIT_ASSERT_EQUAL(OUString("Caption"), getProperty<OUString>(xCharStyle, "LinkStyle")); } +CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testViewCursorTextFrame) +{ + // Given a document with a graphic and holding a reference to that graphic frame: + createSwDoc(); + uno::Sequence<beans::PropertyValue> aInsertArgs = { comphelper::makePropertyValue( + "FileName", m_directories.getURLFromSrc(DATA_DIRECTORY) + "graphic.png") }; + dispatchCommand(mxComponent, ".uno:InsertGraphic", aInsertArgs); + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier( + xModel->getCurrentController(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xViewCursor(xTextViewCursorSupplier->getViewCursor(), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xFrame; + xViewCursor->getPropertyValue("TextFrame") >>= xFrame; + + // When saving to ODT, then make sure the store doesn't fail: + uno::Reference<frame::XStorable> xStorable(xModel, uno::UNO_QUERY); + uno::Sequence<beans::PropertyValue> aStoreArgs + = { comphelper::makePropertyValue("FilterName", OUString("writer8")) }; + // Without the accompanying fix in place, this test would have failed with: + // uno.RuntimeException: "SwXParagraph: disposed or invalid ..." + xStorable->storeToURL(maTempFile.GetURL(), aStoreArgs); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx index 5abffe37e91c..7035f19628d1 100644 --- a/sw/source/core/unocore/unocrsrhelper.cxx +++ b/sw/source/core/unocore/unocrsrhelper.cxx @@ -635,7 +635,8 @@ bool getCursorPropertyValue(const SfxItemPropertyMapEntry& rEntry SwFrameFormat* pFormat; if(eType == SwFlyStartNode && nullptr != (pFormat = pSttNode->GetFlyFormat())) { - if( pAny ) + // Create a wrapper only for text frames, not for graphic or OLE nodes. + if (pAny && !rPam.GetNode().IsNoTextNode()) { uno::Reference<XTextFrame> const xFrame( SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat)); |