sw/qa/core/unocore/data/graphic.png |binary sw/qa/core/unocore/unocore.cxx | 26 ++++++++++++++++++++++++++ sw/source/core/unocore/unocrsrhelper.cxx | 3 ++- 3 files changed, 28 insertions(+), 1 deletion(-)
New commits: commit 0fb7a4324aac356856e215e6c19521cb6871bc77 Author: Miklos Vajna <[email protected]> AuthorDate: Wed Oct 13 17:00:30 2021 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Thu Oct 14 12:06:33 2021 +0200 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. (cherry picked from commit a399b05401fc35ebba4dbd07504fae4a609b3614) Conflicts: sw/qa/core/unocore/unocore.cxx Change-Id: I5e97a826271b0d8a1bf262e43cd8516656b37c3a diff --git a/sw/qa/core/unocore/data/graphic.png b/sw/qa/core/unocore/data/graphic.png new file mode 100644 index 000000000000..fdad35484e7c Binary files /dev/null and b/sw/qa/core/unocore/data/graphic.png differ diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx index a4a39489da60..6ad020077d46 100644 --- a/sw/qa/core/unocore/unocore.cxx +++ b/sw/qa/core/unocore/unocore.cxx @@ -27,6 +27,7 @@ #include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/style/LineSpacing.hpp> #include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/text/XTextViewCursorSupplier.hpp> #include <comphelper/propertyvalue.hxx> #include <toolkit/helper/vclunohelper.hxx> @@ -42,6 +43,7 @@ #include <flyfrm.hxx> #include <fmtanchr.hxx> #include <unotextrange.hxx> +#include <view.hxx> using namespace ::com::sun::star; @@ -108,6 +110,30 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, flyAtParaAnchor) xText->insertTextContent(xAnchor, xFieldmark, false); } +CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testViewCursorTextFrame) +{ + // Given a document with a graphic and holding a reference to that graphic frame: + mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"); + 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 a82e7a1c2308..6a71158d0c3e 100644 --- a/sw/source/core/unocore/unocrsrhelper.cxx +++ b/sw/source/core/unocore/unocrsrhelper.cxx @@ -631,7 +631,8 @@ bool getCursorPropertyValue(const SfxItemPropertySimpleEntry& 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));
