summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2024-04-30 08:44:59 +0200
committerMiklos Vajna <vmiklos@collabora.com>2024-05-09 09:33:22 +0200
commit47c917bcdbffd6423f50a3d970ed45ce06b9061e (patch)
tree720facc179728a32dbf847c69bc407651f9944e0
parent569b31baeea6f877a6568474dfdbba0487b3d729 (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.docxbin0 -> 12178 bytes
-rw-r--r--sw/qa/core/txtnode/txtnode.cxx23
-rw-r--r--sw/source/core/txtnode/thints.cxx4
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
new file mode 100644
index 000000000000..80fecae26d5b
--- /dev/null
+++ b/sw/qa/core/txtnode/data/plain-content-control-copy.docx
Binary files differ
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());