sw/qa/core/txtnode/data/plain-content-control-copy.docx |binary sw/qa/core/txtnode/txtnode.cxx | 23 ++++++++++++++++ sw/source/core/txtnode/thints.cxx | 4 ++ 3 files changed, 26 insertions(+), 1 deletion(-)
New commits: commit 06aeb9c61d50bba7edafe17f9d3513af26b0782f Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Apr 30 08:44:59 2024 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Tue Apr 30 10:12:13 2024 +0200 tdf#159683 sw content controls, plain text: fix crash with the clipboard doc Regression from commit c804c5354855188b5a37219cfe11dc079dc235f4 (sw content control: fix lost properties on copy&paste, 2023-03-10), select a plain text content control, copy it to the clipboard, quit: assertion fails during shutdown because the doc's "placeholder text" char style is still referenced by a client. What happens here is that the SwContentControl copy ctor copies the plain text flag, and that flag is only read in SwTextNode::InsertHint(), so that causes the problem. Note how that code is inconsistent: we avoid the creation of dummy characters in the copy case, but we still try to adjust the start/end of the content control attribute in the copy case, which makes not much sense. Fix the problem by not adjusting the content control attribute boundaries in the copy case, since the original intention was to do thees corrections only at a UI level, during interactive edit. It's not clear why this inconsistency had an influence on the clients of the char style, though. Change-Id: I86b0516464f24fc453dcd97588dafb8afd010a9e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166882 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/core/txtnode/data/plain-content-control-copy.docx b/sw/qa/core/txtnode/data/plain-content-control-copy.docx new file mode 100644 index 000000000000..80fecae26d5b Binary files /dev/null and b/sw/qa/core/txtnode/data/plain-content-control-copy.docx differ diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx index dec97c2ab910..b2bc0cec8b22 100644 --- a/sw/qa/core/txtnode/txtnode.cxx +++ b/sw/qa/core/txtnode/txtnode.cxx @@ -539,6 +539,29 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testSplitFlyAnchorSplit) CPPUNIT_ASSERT_EQUAL(OUString("PortionType::Fly"), aPortionType); } +CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testPlainContentControlCopy) +{ + // Given a document with a plain text content control, all text selected and copied to the + // clipboard: + createSwDoc("plain-content-control-copy.docx"); + SwDocShell* pDocShell = getSwDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + pWrtShell->SelAll(); + { + rtl::Reference<SwTransferable> xTransfer = new SwTransferable(*pWrtShell); + xTransfer->Copy(); + } + + // When closing that document, then make sure we don't crash on shutdown: + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<util::XCloseable> xFrame(xModel->getCurrentController()->getFrame(), + uno::UNO_QUERY); + // Without the accompanying fix in place, this resulted in an assertion failure, a char style + // still had clients by the time it was deleted. + xFrame->close(false); + mxComponent.clear(); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index 60161c3b8f89..c684b005504f 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -1698,7 +1698,9 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode ) // for all of its content. auto* pTextContentControl = static_txtattr_cast<SwTextContentControl*>( GetTextAttrAt(pAttr->GetStart(), RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent)); - if (pTextContentControl) + // If the caller is SwTextNode::CopyText, we just copy an existing attribute, no need to + // correct it. + if (pTextContentControl && !(nMode & SetAttrMode::NOTXTATRCHR)) { auto& rFormatContentControl = static_cast<SwFormatContentControl&>(pTextContentControl->GetAttr());