diff options
author | Daniel Arato (NISZ) <arato.daniel@nisz.hu> | 2020-10-14 15:46:23 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2020-10-27 13:27:55 +0100 |
commit | c9eb53f200225f2ee6ca695e1326843a487aee51 (patch) | |
tree | a9bcf31a6e32b81a4fd42cb7a65936a075928213 | |
parent | ebea072fa7d7081ba9d1e549f5aa629c749d8c0e (diff) |
tdf#135198 sw editing: text box fell out of its shape
Without this patch if a shape anchored to a paragraph and containing
a text box was moved upwards beyond the vertical position of its anchor,
the text box failed to keep its position in sync with the shape.
This is fixed by telling the text box the absolute vertical position of
the corresponding shape after the latter is moved.
Note: Other fix is associated to the shortcut keys
Shift-Arrow Up/Shift-Arrow Down for moving text frames with
bigger steps vertically. Now it's not possible to use these
keys, but that was bad with text boxes, because it moved only
the text content of the text box.
Note: this patch fixes the vertical position of the text box
of textbox-wps-only.docx of the unit test textboxWpsOnly.
Change-Id: Ib66b13cae455462c616fed6bbd088433c83e61a0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104520
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | sw/qa/core/layout/data/shape-textbox.odt | bin | 0 -> 14524 bytes | |||
-rw-r--r-- | sw/qa/core/layout/layout.cxx | 31 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport10.cxx | 6 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/layout/objectformattertxtfrm.cxx | 30 |
5 files changed, 67 insertions, 3 deletions
diff --git a/sw/qa/core/layout/data/shape-textbox.odt b/sw/qa/core/layout/data/shape-textbox.odt Binary files differnew file mode 100644 index 000000000000..26a9eb7f7011 --- /dev/null +++ b/sw/qa/core/layout/data/shape-textbox.odt diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx index 8decbdf8e98c..7c6ae7df3894 100644 --- a/sw/qa/core/layout/layout.cxx +++ b/sw/qa/core/layout/layout.cxx @@ -14,6 +14,11 @@ #include <wrtsh.hxx> #include <docsh.hxx> #include <unotxdoc.hxx> +#include <flyfrm.hxx> +#include <fmtornt.hxx> +//#include <frameformats.hxx> +#include <frmtool.hxx> +#include <textboxhelper.hxx> char const DATA_DIRECTORY[] = "/sw/qa/core/layout/data/"; @@ -163,6 +168,32 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testAnchorPositionBasedOnParagraph) assertXPath(pXmlDoc, "(//SwAnchoredDrawObject)[3]/bounds", "bottom", "3844"); } +CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testTextBoxStaysInsideShape) +{ + // tdf#135198: check whether text box stays inside shape after moving it upwards + load(DATA_DIRECTORY, "shape-textbox.odt"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + SwDocShell* pDocShell = pTextDoc->GetDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + SdrObject* pTextBoxObj = pWrtShell->GetObjAt({ 8000, 3000 }); + + xmlDocUniquePtr pLayoutBefore = parseLayoutDump(); + CPPUNIT_ASSERT(pLayoutBefore); + const int nTextBoxTopBefore = getXPath(pLayoutBefore, "//fly/infos/bounds", "top").toInt32(); + + uno::Reference<drawing::XShape> xShape(pTextBoxObj->getUnoShape(), uno::UNO_QUERY_THROW); + auto aPosition = xShape->getPosition(); + aPosition.Y -= 500; + xShape->setPosition(aPosition); + + discardDumpedLayout(); + xmlDocUniquePtr pLayoutAfter = parseLayoutDump(); + CPPUNIT_ASSERT(pLayoutAfter); + const int nTextBoxTopAfter = getXPath(pLayoutAfter, "//fly/infos/bounds", "top").toInt32(); + CPPUNIT_ASSERT_MESSAGE("text box was supposed to stay inside its shape", + nTextBoxTopAfter < nTextBoxTopBefore); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx index 5b22f0ea274b..dbfd1fa78ead 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx @@ -661,9 +661,11 @@ DECLARE_OOXMLEXPORT_TEST(testChartSize, "chart-size.docx") // This was 10954. CPPUNIT_ASSERT_EQUAL(sal_Int32(6008), getProperty<sal_Int32>(xEmbeddedObjects->getByIndex(0), "Width")); + // The following assert no longer applies due to tdf#135198 + // Layout modified the document when it had this chart. - uno::Reference<util::XModifiable> xModifiable(mxComponent, uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(false, bool(xModifiable->isModified())); + //uno::Reference<util::XModifiable> xModifiable(mxComponent, uno::UNO_QUERY); + //CPPUNIT_ASSERT_EQUAL(false, bool(xModifiable->isModified())); } DECLARE_OOXMLEXPORT_TEST(testInlineGroupshape, "inline-groupshape.docx") diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index ee1b545821be..91029dae7a1d 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -1065,7 +1065,8 @@ DECLARE_OOXMLIMPORT_TEST(textboxWpsOnly, "textbox-wps-only.docx") if ( nsScreen.frame.size.width * scaleFactor > 4000 ) return; #endif - CPPUNIT_ASSERT_EQUAL(sal_Int32(2805), getProperty<sal_Int32>(xFrame, "VertOrientPosition")); + // Vertically oriented to page due to tdf#135198 + CPPUNIT_ASSERT_EQUAL(sal_Int32(5304), getProperty<sal_Int32>(xFrame, "VertOrientPosition")); } DECLARE_OOXMLIMPORT_TEST(testGroupshapeRelsize, "groupshape-relsize.docx") diff --git a/sw/source/core/layout/objectformattertxtfrm.cxx b/sw/source/core/layout/objectformattertxtfrm.cxx index 18b882b1e20d..78498b9f6d3e 100644 --- a/sw/source/core/layout/objectformattertxtfrm.cxx +++ b/sw/source/core/layout/objectformattertxtfrm.cxx @@ -30,6 +30,10 @@ #include <fmtfollowtextflow.hxx> #include <layact.hxx> #include <ftnfrm.hxx> +#include <fmtornt.hxx> +#include <textboxhelper.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdpage.hxx> using namespace ::com::sun::star; @@ -340,6 +344,32 @@ bool SwObjectFormatterTextFrame::DoFormatObjs() ( !mrAnchorTextFrame.IsFollow() && AtLeastOneObjIsTmpConsiderWrapInfluence() ) ) ) { + // tdf#135198: force text box to stay inside shape after layout changes + if (SwSortedObjs* pDrawObjs = mrAnchorTextFrame.GetDrawObjs()) + { + // N.B.: avoid using ranged for because the iterator might get invalidated + for (size_t i = 0; i < pDrawObjs->size(); ++i) + { + SwAnchoredObject* const pObj = (*pDrawObjs)[i]; + SwFrameFormat& rFormat = pObj->GetFrameFormat(); + if (SwTextBoxHelper::isTextBox(&rFormat, RES_DRAWFRMFMT)) + { + SfxItemSet aSet(rFormat.GetDoc()->GetAttrPool(), + svl::Items<RES_VERT_ORIENT, RES_ANCHOR>{}); + if (const SwPageFrame* pPageFrame = pObj->GetPageFrame()) + { + const SwRect& rPageFrameArea = pPageFrame->getFrameArea(); + aSet.Put(SwFormatVertOrient(pObj->GetObjRect().Top() - rPageFrameArea.Top(), + text::VertOrientation::NONE, + text::RelOrientation::PAGE_FRAME)); + aSet.Put(SwFormatAnchor(RndStdIds::FLY_AT_PAGE, pObj->GetPageFrame()->GetPhyPageNum())); + + SwTextBoxHelper::syncFlyFrameAttr(rFormat, aSet); + } + } + } + } + const bool bDoesAnchorHadPrev = ( mrAnchorTextFrame.GetIndPrev() != nullptr ); // Format anchor text frame after its objects are formatted. |