[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