[Libreoffice-commits] core.git: Branch 'libreoffice-7-0' - sw/qa sw/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Tue Nov 3 20:59:15 UTC 2020
sw/qa/core/frmedt/data/paste-fly-in-textbox.docx |binary
sw/qa/core/frmedt/frmedt.cxx | 30 ++++++++++++++++
sw/source/core/frmedt/fecopy.cxx | 42 +++++++++++++++++++++++
3 files changed, 72 insertions(+)
New commits:
commit bdda0c123b28531f515c37faf804d9ed1659074f
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Nov 2 21:01:14 2020 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Nov 3 21:58:38 2020 +0100
tdf#135893 sw paste: fix copying fly frame in textbox twice
Regression from commit c7307c77254557646f33017af915f6808a861e29
(fdo#82191 sw::DocumentLayoutManager: copy textbox content of draw
formats, 2014-08-15), the problem is that the fly+draw format copies the
fly content recursively already, so when we would copy all special
formats of the document, the inner fly frame is copied twice.
This is normally not a problem for fly frames (where you can't select
multiple fly frames at the same time), nor a problem for draw frames
(which have no sw content), but it's a problem for the combination of
these, TextBoxes.
Fix the problem by ignoring fly frames which are anchored in such
TextBoxes: we do the same for fly frames which have an associated draw
format already.
(cherry picked from commit 3ac675736066b47da7329269a01c1ef4a9cfe72a)
Conflicts:
sw/qa/core/frmedt/frmedt.cxx
Change-Id: I3376beb414f91abfa6f3f5640f825ccae34911c2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105247
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sw/qa/core/frmedt/data/paste-fly-in-textbox.docx b/sw/qa/core/frmedt/data/paste-fly-in-textbox.docx
new file mode 100644
index 000000000000..75bf13b13b67
Binary files /dev/null and b/sw/qa/core/frmedt/data/paste-fly-in-textbox.docx differ
diff --git a/sw/qa/core/frmedt/frmedt.cxx b/sw/qa/core/frmedt/frmedt.cxx
index c737187887c9..d0929c25d7f8 100644
--- a/sw/qa/core/frmedt/frmedt.cxx
+++ b/sw/qa/core/frmedt/frmedt.cxx
@@ -19,6 +19,7 @@
#include <drawdoc.hxx>
#include <dcontact.hxx>
#include <frameformats.hxx>
+#include <swdtflvr.hxx>
static char const DATA_DIRECTORY[] = "/sw/qa/core/frmedt/data/";
@@ -106,6 +107,35 @@ CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testVertPosFromBottomBoundingBox)
CPPUNIT_ASSERT_EQUAL(-1 * nPagePrintAreaBottom, aBoundRect.Pos().getY());
}
+CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testPasteFlyInTextBox)
+{
+ // Given a document that contains a textbox, which contains an sw image (fly frame)
+ load(DATA_DIRECTORY, "paste-fly-in-textbox.docx");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ SwDocShell* pDocShell = pTextDoc->GetDocShell();
+ SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+ SwDoc* pDoc = pDocShell->GetDoc();
+ SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
+ SdrObject* pObject = pPage->GetObj(0);
+ pWrtShell->SelectObj(Point(), 0, pObject);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pDoc->GetSpzFrameFormats()->GetFormatCount());
+ rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
+ pTransfer->Cut();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pDoc->GetSpzFrameFormats()->GetFormatCount());
+ TransferableDataHelper aHelper(pTransfer.get());
+
+ // When pasting that to an empty document.
+ SwTransferable::Paste(*pWrtShell, aHelper);
+
+ // Then we should have the image only once: 3 formats (draw+fly formats for the textbox and a
+ // fly format for the image).
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 3
+ // - Actual : 4
+ // i.e. the image was pasted twice.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pDoc->GetSpzFrameFormats()->GetFormatCount());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index 2522c039ce0d..67027a4c5b9e 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -671,6 +671,41 @@ namespace {
{
return rPaM.HasMark() && *rPaM.GetPoint() != *rPaM.GetMark();
}
+
+ /// Is pFormat anchored in a fly frame which has an associated draw format?
+ bool IsInTextBox(const SwFrameFormat* pFormat)
+ {
+ const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
+ const SwPosition* pPosition = rAnchor.GetContentAnchor();
+ if (!pPosition)
+ {
+ return false;
+ }
+
+ const SwStartNode* pFlyNode = pPosition->nNode.GetNode().FindFlyStartNode();
+ if (!pFlyNode)
+ {
+ return false;
+ }
+
+ for ( const auto& pSpzFormat : *pFormat->GetDoc()->GetSpzFrameFormats() )
+ {
+ if (pSpzFormat->Which() != RES_FLYFRMFMT)
+ {
+ continue;
+ }
+
+ const SwNodeIndex* pIdx = pSpzFormat->GetContent().GetContentIdx();
+ if (!pIdx || pFlyNode != &pIdx->GetNode())
+ {
+ continue;
+ }
+
+ return SwTextBoxHelper::isTextBox(pSpzFormat, RES_FLYFRMFMT);
+ }
+
+ return false;
+ }
}
bool SwFEShell::Paste( SwDoc* pClpDoc, bool bNestedTable )
@@ -958,6 +993,13 @@ bool SwFEShell::Paste( SwDoc* pClpDoc, bool bNestedTable )
if (pCpyObj && CheckControlLayer(pCpyObj))
continue;
}
+ else if (pCpyFormat->Which() == RES_FLYFRMFMT && IsInTextBox(pCpyFormat))
+ {
+ // This is a fly frame which is anchored in a TextBox, ignore it as
+ // it's already copied as part of copying the content of the
+ // TextBox.
+ continue;
+ }
// Ignore TextBoxes, they are already handled in sw::DocumentLayoutManager::CopyLayoutFormat().
if (SwTextBoxHelper::isTextBox(pCpyFormat, RES_FLYFRMFMT))
More information about the Libreoffice-commits
mailing list