[Libreoffice-commits] core.git: sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Jun 30 07:29:12 UTC 2020


 sw/qa/core/txtnode/data/textbox-copy-anchor.docx        |binary
 sw/qa/core/txtnode/txtnode.cxx                          |   32 ++++++++++++++++
 sw/source/core/doc/DocumentContentOperationsManager.cxx |    8 ++++
 sw/source/core/txtnode/atrflyin.cxx                     |   10 +++++
 4 files changed, 50 insertions(+)

New commits:
commit 682e0488df819c191c13a03758fad0690706e508
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Jun 29 21:05:27 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Jun 30 09:28:31 2020 +0200

    tdf#134099 sw: fix textbox anchors on copy-paste and undo
    
    Regression from commit c7307c77254557646f33017af915f6808a861e29
    (fdo#82191 sw::DocumentLayoutManager: copy textbox content of draw
    formats, 2014-08-15), without which this problem gets hidden, as copy
    breaks the textbox into 2 pieces, so the textbox codepaths are no longer
    hit.
    
    The direct problem is that SwHistorySetFormat::SetInDoc() uses a raw
    node index into the nodes array, which is past the end of the nodes
    array.
    
    Root cause is that we have this invariant that actions and their undo
    has to be in sync, otherwise raw node indexes no longer work. In this
    case, SwUndoSaveContent::DelContentIndex() did not delete a fly frame
    format, because it was out of range, as it had a wrong anchor.
    
    Fix this in SwTextFlyCnt::SetAnchor(), so that whenever the anchor of a
    draw format is set via that function, we update its textbox as well.
    
    Also fix a related problem when fly formats were copied twice.
    
    Change-Id: I0d6c9069544c405eb20c5fed65fb40423b0adc84
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97457
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/core/txtnode/data/textbox-copy-anchor.docx b/sw/qa/core/txtnode/data/textbox-copy-anchor.docx
new file mode 100644
index 000000000000..b835097f1b9b
Binary files /dev/null and b/sw/qa/core/txtnode/data/textbox-copy-anchor.docx differ
diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index 0638fe742ff3..664a7ac26c7d 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -11,6 +11,10 @@
 
 #include <vcl/gdimtf.hxx>
 
+#include <fmtanchr.hxx>
+#include <frameformats.hxx>
+#include <wrtsh.hxx>
+
 static char const DATA_DIRECTORY[] = "/sw/qa/core/txtnode/data/";
 
 /// Covers sw/source/core/txtnode/ fixes.
@@ -38,6 +42,34 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testBtlrCellChinese)
     assertXPath(pXmlDoc, "//font[1]", "vertical", "false");
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testTextBoxCopyAnchor)
+{
+    load(DATA_DIRECTORY, "textbox-copy-anchor.docx");
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwDocShell* pShell = pTextDoc->GetDocShell();
+    SwWrtShell* pWrtShell = pShell->GetWrtShell();
+    SwDoc aClipboard;
+    pWrtShell->SelAll();
+    pWrtShell->Copy(&aClipboard);
+    pWrtShell->SttEndDoc(/*bStart=*/false);
+    pWrtShell->Paste(&aClipboard);
+
+    const SwFrameFormats& rFormats = *pShell->GetDoc()->GetSpzFrameFormats();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 4
+    // - Actual  : 6
+    // i.e. 2 fly frames were copied twice.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rFormats.size());
+
+    SwPosition aDrawAnchor1 = *rFormats[0]->GetAnchor().GetContentAnchor();
+    SwPosition aFlyAnchor1 = *rFormats[1]->GetAnchor().GetContentAnchor();
+    CPPUNIT_ASSERT_EQUAL(aFlyAnchor1.nNode, aDrawAnchor1.nNode);
+    SwPosition aDrawAnchor2 = *rFormats[2]->GetAnchor().GetContentAnchor();
+    SwPosition aFlyAnchor2 = *rFormats[3]->GetAnchor().GetContentAnchor();
+    // This also failed, aFlyAnchor2 was wrong, as it got out of sync with aDrawAnchor2.
+    CPPUNIT_ASSERT_EQUAL(aFlyAnchor2.nNode, aDrawAnchor2.nNode);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index ea1aa8b001be..4bb4325134d9 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3788,6 +3788,14 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl(
             }
         }
 
+        // Ignore TextBoxes, they are already handled in
+        // sw::DocumentLayoutManager::CopyLayoutFormat().
+        if (SwTextBoxHelper::isTextBox(it->GetFormat(), RES_FLYFRMFMT))
+        {
+            it = aSet.erase(it);
+            continue;
+        }
+
         // Copy the format and set the new anchor
         aVecSwFrameFormat.push_back( pDest->getIDocumentLayoutAccess().CopyLayoutFormat( *(*it).GetFormat(),
                 aAnchor, false, true ) );
diff --git a/sw/source/core/txtnode/atrflyin.cxx b/sw/source/core/txtnode/atrflyin.cxx
index 3fc62f51a368..902d3bda3a1e 100644
--- a/sw/source/core/txtnode/atrflyin.cxx
+++ b/sw/source/core/txtnode/atrflyin.cxx
@@ -33,6 +33,7 @@
 #include <objectformatter.hxx>
 #include <calbck.hxx>
 #include <dcontact.hxx>
+#include <textboxhelper.hxx>
 
 SwFormatFlyCnt::SwFormatFlyCnt( SwFrameFormat *pFrameFormat )
     : SfxPoolItem( RES_TXTATR_FLYCNT ),
@@ -200,6 +201,15 @@ void SwTextFlyCnt::SetAnchor( const SwTextNode *pNode )
             }
         }
         pFormat->SetFormatAttr( aAnchor );  // only set the anchor
+
+        // If the draw format has a TextBox, then set its anchor as well.
+        if (SwFrameFormat* pTextBox
+            = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
+        {
+            SwFormatAnchor aTextBoxAnchor(pTextBox->GetAnchor());
+            aTextBoxAnchor.SetAnchor(aAnchor.GetContentAnchor());
+            pTextBox->SetFormatAttr(aTextBoxAnchor);
+        }
     }
 
     // The node may have several SwTextFrames - for every SwTextFrame a


More information about the Libreoffice-commits mailing list