diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2024-04-30 08:44:59 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2024-05-09 09:33:22 +0200 |
commit | 47c917bcdbffd6423f50a3d970ed45ce06b9061e (patch) | |
tree | 720facc179728a32dbf847c69bc407651f9944e0 | |
parent | 569b31baeea6f877a6568474dfdbba0487b3d729 (diff) |
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 <vmiklos@collabora.com>
Tested-by: Jenkins
(cherry picked from commit 06aeb9c61d50bba7edafe17f9d3513af26b0782f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167311
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
(cherry picked from commit 32616609c788aa1cf0837af0f387390a23de1766)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167375
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
-rw-r--r-- | sw/qa/core/txtnode/data/plain-content-control-copy.docx | bin | 0 -> 12178 bytes | |||
-rw-r--r-- | sw/qa/core/txtnode/txtnode.cxx | 23 | ||||
-rw-r--r-- | sw/source/core/txtnode/thints.cxx | 4 |
3 files changed, 26 insertions, 1 deletions
diff --git a/sw/qa/core/txtnode/data/plain-content-control-copy.docx b/sw/qa/core/txtnode/data/plain-content-control-copy.docx Binary files differnew file mode 100644 index 000000000000..80fecae26d5b --- /dev/null +++ b/sw/qa/core/txtnode/data/plain-content-control-copy.docx diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx index c2df8a407e69..be4d97190251 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 cf5e1ff1cccf..c499294f4f26 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -1700,7 +1700,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()); |