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

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 27 07:05:42 UTC 2021


 sw/qa/core/doc/data/textbox-makeflyframe.docx |binary
 sw/qa/core/doc/doc.cxx                        |   36 ++++++++++++++++++++++++++
 sw/source/core/doc/DocumentLayoutManager.cxx  |    8 +++++
 sw/source/core/txtnode/atrflyin.cxx           |    9 ++++++
 4 files changed, 53 insertions(+)

New commits:
commit feeaa5d3ca0c784344549816fbaab2c8716b4105
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Apr 26 21:01:45 2021 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Apr 27 09:05:03 2021 +0200

    tdf#138604 sw textbox copy: fix missing fly frames of as-char draw frame
    
    Regression from commit 682e0488df819c191c13a03758fad0690706e508
    (tdf#134099 sw: fix textbox anchors on copy-paste and undo, 2020-06-29),
    now that we don't copy draw+fly format pairs more than once, the fly frame
    of a fly format was missing.
    
    This was broken because
    sw::DocumentContentOperationsManager::CopyFlyInFlyImpl() calls
    CopyLayoutFormat() with bMakeFrames=true, but the frame format list
    doesn't contain as-char frames.
    
    For as-char frames CopyLayoutFormat() is called by
    SwTextFlyCnt::CopyFlyFormat() instead, but with bMakeFrames=false, so
    the fly frame's layout frame were never made.
    
    Fix the problem by explicitly making frames in
    DocumentLayoutManager::CopyLayoutFormat(), which also requires
    delete+make in SwTextFlyCnt::SetAnchor(). [ This is now consistent with
    the start of SwTextFlyCnt::SetAnchor(), which also deletes frames for
    fly frame formats. Otherwise CppunitTest_sw_core_txtnode would crash in
    testTextBoxCopyAnchor. ]
    
    Change-Id: I87003ee09ca75b9fecd70a1aa5c42f762f715be8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114680
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/core/doc/data/textbox-makeflyframe.docx b/sw/qa/core/doc/data/textbox-makeflyframe.docx
new file mode 100644
index 000000000000..9e26cda3c6a6
Binary files /dev/null and b/sw/qa/core/doc/data/textbox-makeflyframe.docx differ
diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx
index b1574321320d..68d5992b05be 100644
--- a/sw/qa/core/doc/doc.cxx
+++ b/sw/qa/core/doc/doc.cxx
@@ -16,6 +16,8 @@
 #include <vcl/errinf.hxx>
 #include <vcl/event.hxx>
 #include <editeng/langitem.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
 
 #include <wrtsh.hxx>
 #include <fmtanchr.hxx>
@@ -24,6 +26,9 @@
 #include <edtwin.hxx>
 #include <view.hxx>
 #include <ndtxt.hxx>
+#include <swdtflvr.hxx>
+#include <cmdid.h>
+#include <unotxdoc.hxx>
 
 constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/core/doc/data/";
 
@@ -129,6 +134,37 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testTextBoxZOrder)
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(2), pEllipseShape->GetOrdNum());
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testTextBoxMakeFlyFrame)
+{
+    // Given a document with an as-char textbox (as-char draw format + at-char fly format):
+    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "textbox-makeflyframe.docx");
+
+    // When cutting the textbox and pasting it to a new document:
+    SwView* pView = pDoc->GetDocShell()->GetView();
+    pView->GetViewFrame()->GetDispatcher()->Execute(FN_CNTNT_TO_NEXT_FRAME, SfxCallMode::SYNCHRON);
+    pView->StopShellTimer();
+    SwDocShell* pDocShell = pDoc->GetDocShell();
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+    rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
+    pTransfer->Cut();
+    TransferableDataHelper aHelper(pTransfer);
+    uno::Reference<lang::XComponent> xDoc2
+        = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument", {});
+    SwXTextDocument* pTextDoc2 = dynamic_cast<SwXTextDocument*>(xDoc2.get());
+    SwDocShell* pDocShell2 = pTextDoc2->GetDocShell();
+    SwWrtShell* pWrtShell2 = pDocShell2->GetWrtShell();
+    SwTransferable::Paste(*pWrtShell2, aHelper);
+
+    // Then make sure its fly frame is created.
+    mxComponent->dispose();
+    mxComponent = xDoc2;
+    xmlDocUniquePtr pLayout = parseLayoutDump();
+    // Without the accompanying fix in place, this test would have failed, because the first text
+    // frame in the body frame had an SwAnchoredDrawObject anchored to it, but not a fly frame, so
+    // a blank square was painted, not the image.
+    assertXPath(pLayout, "/root/page/body/txt/anchored/fly", 1);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentLayoutManager.cxx b/sw/source/core/doc/DocumentLayoutManager.cxx
index 95362f1e4be3..d4a92a09a69c 100644
--- a/sw/source/core/doc/DocumentLayoutManager.cxx
+++ b/sw/source/core/doc/DocumentLayoutManager.cxx
@@ -474,6 +474,14 @@ SwFrameFormat *DocumentLayoutManager::CopyLayoutFormat(
         // presumably these anchors are supported though not sure
         assert(RndStdIds::FLY_AT_CHAR == boxAnchor.GetAnchorId() || RndStdIds::FLY_AT_PARA == boxAnchor.GetAnchorId()
         || boxAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE);
+
+        if (!bMakeFrames && rNewAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
+        {
+            // If the draw format is as-char, then it will be copied with bMakeFrames=false, but
+            // doing the same for the fly format would result in not making fly frames at all.
+            bMakeFrames = true;
+        }
+
         SwFrameFormat* pDestTextBox = CopyLayoutFormat(*pSourceTextBox,
                 boxAnchor, bSetTextFlyAtt, bMakeFrames);
         SwAttrSet aSet(pDest->GetAttrSet());
diff --git a/sw/source/core/txtnode/atrflyin.cxx b/sw/source/core/txtnode/atrflyin.cxx
index cfb01bbace4f..7c1562ad49c3 100644
--- a/sw/source/core/txtnode/atrflyin.cxx
+++ b/sw/source/core/txtnode/atrflyin.cxx
@@ -218,6 +218,11 @@ void SwTextFlyCnt::SetAnchor( const SwTextNode *pNode )
             {
                 pTextBox->LockModify();
             }
+            else
+            {
+                // Otherwise delete fly frames on anchor change.
+                pTextBox->DelFrames();
+            }
 
             pTextBox->SetFormatAttr(aTextBoxAnchor);
 
@@ -227,6 +232,10 @@ void SwTextFlyCnt::SetAnchor( const SwTextNode *pNode )
                 aPos.nNode.GetNode().AddAnchoredFly(pTextBox);
                 pTextBox->UnlockModify();
             }
+            else
+            {
+                pTextBox->MakeFrames();
+            }
         }
     }
 


More information about the Libreoffice-commits mailing list