tdf#156318 sw floattable: fix follow text flow handling on interactive edit
Once the bugdoc has 1 col for pages, setting the top and bottom margins to 2.5cm created a split fly, but the follow fly was on page 3, not on page 2. What happened is that the layout was already wrong before calling into SwFrame::GetNextFlyLeaf() (that does the split), the "follow text flow" feature shifted the fly down (top was originally 1341, then the increased margin means 2475, but an additional 4329 was set), and then the fly was created on the wrong page. Fix the problem by not calling GetAnchoredObj().SetObjTop() in SwToContentAnchoredObjectPosition::CalcPosition() when the fly doesn't fit anymore, this way the fly can shrink, a follow can be created and some of the content will be moved to the follow fly, leading to a correct split fly on pages 1 & 2. This also fixes the previously appearing "fly frame has negative height now" warnings on setting the page margin. Change-Id: I75bf9cfa19dc5c7ce9607417d6a4121b8e85ac47 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156506 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
This commit is contained in:
parent
1761680a8f
commit
401c175d1b
4 changed files with 56 additions and 11 deletions
|
@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_core_objectpositioning, \
|
|||
comphelper \
|
||||
cppu \
|
||||
cppuhelper \
|
||||
editeng \
|
||||
sal \
|
||||
sfx \
|
||||
subsequenttest \
|
||||
|
@ -70,6 +71,9 @@ $(eval $(call gb_CppunitTest_use_uiconfigs,sw_core_objectpositioning, \
|
|||
modules/swriter \
|
||||
))
|
||||
|
||||
# assert if font/glyph fallback occurs
|
||||
$(eval $(call gb_CppunitTest_set_non_application_font_use,sw_core_objectpositioning,abort))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_more_fonts,sw_core_objectpositioning))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
|
|
Binary file not shown.
|
@ -12,6 +12,8 @@
|
|||
#include <com/sun/star/text/VertOrientation.hpp>
|
||||
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
|
||||
|
||||
#include <editeng/ulspitem.hxx>
|
||||
|
||||
#include <wrtsh.hxx>
|
||||
#include <unotxdoc.hxx>
|
||||
#include <docsh.hxx>
|
||||
|
@ -21,18 +23,21 @@
|
|||
#include <sortedobjs.hxx>
|
||||
#include <anchoredobject.hxx>
|
||||
#include <flyfrm.hxx>
|
||||
#include <frmatr.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
/// Covers sw/source/core/objectpositioning/ fixes.
|
||||
class SwCoreObjectpositioningTest : public SwModelTestBase
|
||||
class Test : public SwModelTestBase
|
||||
{
|
||||
public:
|
||||
SwCoreObjectpositioningTest()
|
||||
Test()
|
||||
: SwModelTestBase("/sw/qa/core/objectpositioning/data/")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testOverlapCrash)
|
||||
CPPUNIT_TEST_FIXTURE(Test, testOverlapCrash)
|
||||
{
|
||||
// Load a document with 2 images.
|
||||
createSwDoc("overlap-crash.odt");
|
||||
|
@ -51,7 +56,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testOverlapCrash)
|
|||
pWrtShell->SplitNode();
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVertPosFromBottom)
|
||||
CPPUNIT_TEST_FIXTURE(Test, testVertPosFromBottom)
|
||||
{
|
||||
// Create a document, insert a shape and position it 1cm above the bottom of the body area.
|
||||
createSwDoc();
|
||||
|
@ -80,7 +85,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVertPosFromBottom)
|
|||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(565), nBodyBottom - nAnchoredBottom);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVertAlignBottomMargin)
|
||||
CPPUNIT_TEST_FIXTURE(Test, testVertAlignBottomMargin)
|
||||
{
|
||||
// Create a document, insert three shapes and align it the bottom,center,top of page print area bottom.
|
||||
// The size of shapes are 284 ~ 0.5cm
|
||||
|
@ -151,7 +156,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVertAlignBottomMargin)
|
|||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nThirdShapeTop - nBodyBottom);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVertAlignBottomMarginWithFooter)
|
||||
CPPUNIT_TEST_FIXTURE(Test, testVertAlignBottomMarginWithFooter)
|
||||
{
|
||||
// Load an empty document with footer.
|
||||
createSwDoc("bottom-margin-with-footer.docx");
|
||||
|
@ -223,7 +228,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVertAlignBottomMarginWithF
|
|||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nThirdShapeTop - nBodyBottom);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testInsideOutsideVertAlignBottomMargin)
|
||||
CPPUNIT_TEST_FIXTURE(Test, testInsideOutsideVertAlignBottomMargin)
|
||||
{
|
||||
// Load a document, with two shapes.
|
||||
// The shapes align the outside and inside of page print area bottom.
|
||||
|
@ -244,7 +249,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testInsideOutsideVertAlignBott
|
|||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nBodyBottom - nSecondShapeInside);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVMLVertAlignBottomMargin)
|
||||
CPPUNIT_TEST_FIXTURE(Test, testVMLVertAlignBottomMargin)
|
||||
{
|
||||
// Load a document, with five shapes.
|
||||
// The shapes align the top,center,bottom,outside and inside of page print area bottom.
|
||||
|
@ -286,7 +291,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVMLVertAlignBottomMargin)
|
|||
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), nFifthVMLShapeOutside - nPageBottom);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testFloatingTableOverlapNever)
|
||||
CPPUNIT_TEST_FIXTURE(Test, testFloatingTableOverlapNever)
|
||||
{
|
||||
// Given a document with two floating tables, positioned in a way that normally these would
|
||||
// overlap, but SwFormatWrapInfluenceOnObjPos::mbAllowOverlap == false explicitly asks to avoid
|
||||
|
@ -313,7 +318,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testFloatingTableOverlapNever)
|
|||
CPPUNIT_ASSERT_GREATER(pFlyFrame1->getFrameArea().Bottom(), pFlyFrame2->getFrameArea().Top());
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testFloatingTableVertOrientTop)
|
||||
CPPUNIT_TEST_FIXTURE(Test, testFloatingTableVertOrientTop)
|
||||
{
|
||||
// Given a document with a vert-orient=from-top anchored floating table:
|
||||
createSwDoc("floattable-vert-orient-top.odt");
|
||||
|
@ -337,6 +342,37 @@ CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testFloatingTableVertOrientTop
|
|||
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs.size());
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testFloatingTableFollowWrongPage)
|
||||
{
|
||||
// Given a document with text on 2 pages, the first page has a fly frame that can split:
|
||||
createSwDoc("floattable-follow-on-wrong-page.odt");
|
||||
|
||||
// When increasing the top and bottom margins from 0.5cm to 2.5cm:
|
||||
SwDoc* pDoc = getSwDoc();
|
||||
SwPageDesc aStandard(pDoc->GetPageDesc(0));
|
||||
SvxULSpaceItem aPageMargin(aStandard.GetMaster().GetULSpace());
|
||||
aPageMargin.SetUpper(1417);
|
||||
aPageMargin.SetLower(1417);
|
||||
aStandard.GetMaster().SetFormatAttr(aPageMargin);
|
||||
pDoc->ChgPageDesc(0, aStandard);
|
||||
|
||||
// Then make sure the first and second page has fly frames:
|
||||
SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
|
||||
auto pPage1 = pLayout->Lower()->DynCastPageFrame();
|
||||
CPPUNIT_ASSERT(pPage1);
|
||||
CPPUNIT_ASSERT(pPage1->GetSortedObjs());
|
||||
const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs();
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage1Objs.size());
|
||||
auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
|
||||
CPPUNIT_ASSERT(pPage2);
|
||||
// Without the accompanying fix in place, this test would have failed, page 2 had no fly frame
|
||||
// (page 3 had one).
|
||||
CPPUNIT_ASSERT(pPage2->GetSortedObjs());
|
||||
const SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs();
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage2Objs.size());
|
||||
}
|
||||
}
|
||||
|
||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -193,6 +193,8 @@ void SwToContentAnchoredObjectPosition::CalcPosition()
|
|||
// If true, this means that the anchored object is a split fly frame and it's not a master but
|
||||
// one of the follows.
|
||||
bool bFollowSplitFly = false;
|
||||
// The anchored object is a fly that is allowed to split.
|
||||
bool bSplitFly = false;
|
||||
{
|
||||
// if object is at-character anchored, determine character-rectangle
|
||||
// and frame, position has to be oriented at.
|
||||
|
@ -257,6 +259,7 @@ void SwToContentAnchoredObjectPosition::CalcPosition()
|
|||
// Anchored object has a precede, so it's a follow.
|
||||
bFollowSplitFly = true;
|
||||
}
|
||||
bSplitFly = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -952,7 +955,9 @@ void SwToContentAnchoredObjectPosition::CalcPosition()
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
// Don't move split flys around for follow text flow purposes; if they don't fit their
|
||||
// parent anymore, they will shrink and part of the content will move to the follow fly.
|
||||
else if (!bSplitFly)
|
||||
{
|
||||
// follow text flow
|
||||
const bool bInFootnote = rAnchorTextFrame.IsInFootnote();
|
||||
|
|
Loading…
Reference in a new issue