summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Arato (NISZ) <arato.daniel@nisz.hu>2020-10-14 15:46:23 +0200
committerLászló Németh <nemeth@numbertext.org>2020-10-27 13:27:55 +0100
commitc9eb53f200225f2ee6ca695e1326843a487aee51 (patch)
treea9bcf31a6e32b81a4fd42cb7a65936a075928213
parentebea072fa7d7081ba9d1e549f5aa629c749d8c0e (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.odtbin0 -> 14524 bytes
-rw-r--r--sw/qa/core/layout/layout.cxx31
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport10.cxx6
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx3
-rw-r--r--sw/source/core/layout/objectformattertxtfrm.cxx30
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
new file mode 100644
index 000000000000..26a9eb7f7011
--- /dev/null
+++ b/sw/qa/core/layout/data/shape-textbox.odt
Binary files differ
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.