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 32616609c788aa1cf0837af0f387390a23de1766
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Apr 30 08:44:59 2024 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed May 8 10:57:56 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
    (cherry picked from commit 06aeb9c61d50bba7edafe17f9d3513af26b0782f)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167311
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

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 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());

Reply via email to