sw/qa/core/layout/calcmove.cxx     |   31 +++++++++++++++++++++++++++++++
 sw/source/core/layout/calcmove.cxx |   17 +++++++++++++++--
 sw/source/core/layout/pagechg.cxx  |    6 +++++-
 3 files changed, 51 insertions(+), 3 deletions(-)

New commits:
commit ba7199da2e6ec9d58475373f264326fbeb31f4bd
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Oct 2 08:15:45 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Oct 2 09:35:40 2024 +0200

    tdf#156218 sw hide whitespace: fix increased page size on new para at doc 
end
    
    Create a document of 1 page, add empty paragraphs, so the next empty
    paragraph would create a second page. Hide whitespace, then add that
    paragraph: no second page is created.
    
    Seems this is a regression from commit
    2c23d4ee1e1370b20560e47db7efaeaac1d94b26 (tdf#96515 sw Hide Whitespace:
    avoid creating unneeded page frames, 2015-12-16), because previously we
    had the opposite problem: creating new page frames all the time, even if
    the current page frame could grow.
    
    Fix the problem by:
    
    1) In SwPageFrame::MakeAll(), fix the size of the page frame when
    switching to hide whitespace mode, so margins are not part of the
    height. At least the last paragraph of the doc is now near the bottom of
    the page, so it's more likely to create a new page. This means now we're
    back to still tweaking the size of the last page: but we used to
    determine the height based on just content and here we just ignore
    top/bottom margin.
    
    2) In SwPageFrame::CheckPageHeightValidForHideWhitespace(), handle the
    top/bottom margins, otherwise we'll think that the page frame can
    still grow, when it should not.
    
    3) Finally in SwPageFrame::MakeAll(), when we determine the height for
    non-last pages, the text frame for the new paragraph is already
    inserted, so limit the page frame height: if "content height" is more
    than "height - whitespace", then that limit should be the height,
    otherwise the page frame height will grow forever.
    
    Change-Id: I1125c31ec8b387df41c0881af98469d56ed773db
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174368
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/core/layout/calcmove.cxx b/sw/qa/core/layout/calcmove.cxx
index 8098dc238fc0..cd9ac954ac68 100644
--- a/sw/qa/core/layout/calcmove.cxx
+++ b/sw/qa/core/layout/calcmove.cxx
@@ -11,6 +11,9 @@
 
 #include <test/xmldocptr.hxx>
 
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+
 namespace
 {
 /// Covers sw/source/core/layout/calcmove.cxx fixes.
@@ -82,6 +85,34 @@ CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMarginFly)
     // is a Writer feature.
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4000), nParaTopMargin);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testHideWhitespaceGrowingLastPage)
+{
+    // Given a document with a full first page, then hiding whitespace:
+    createSwDoc();
+    SwDocShell* pDocShell = getSwDocShell();
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    while (getPages() == 1)
+    {
+        pWrtShell->SplitNode();
+    }
+    pWrtShell->DelLeft();
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
+    aViewOptions.SetHideWhitespaceMode(true);
+    pWrtShell->ApplyViewOptions(aViewOptions);
+
+    // When adding a new paragraph at doc end:
+    pWrtShell->SplitNode();
+
+    // Then make sure a new page is created:
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 2
+    // - Actual  : 1
+    // i.e. the page was growing instead of creating a new page when it 
already had a max size.
+    CPPUNIT_ASSERT_EQUAL(2, getPages());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/calcmove.cxx 
b/sw/source/core/layout/calcmove.cxx
index 475420e32d78..8f99488ca86b 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -907,11 +907,18 @@ void SwPageFrame::MakeAll(vcl::RenderContext* 
pRenderContext)
                     setFramePrintAreaValid(true);
                     continue;
                 }
-                else if (pSh && pSh->GetViewOptions()->IsWhitespaceHidden() && 
pRootFrame->GetLastPage() != this)
+                else if (pSh && pSh->GetViewOptions()->IsWhitespaceHidden())
                 {
                     tools::Long height = 0;
                     SwLayoutFrame *pBody = FindBodyCont();
-                    if ( pBody && pBody->Lower() && 
pBody->Lower()->IsColumnFrame() )
+                    SwTwips nFullBodyHeight = pAttrs->GetSize().Height() - 
pAttrs->CalcTop() - pAttrs->CalcBottom();
+                    if (pRootFrame->GetLastPage() == this)
+                    {
+                        // Last page is only reduced by the top/bottom margin, 
the body frame height
+                        // is not reduced.
+                        height = nFullBodyHeight;
+                    }
+                    else if ( pBody && pBody->Lower() && 
pBody->Lower()->IsColumnFrame() )
                     {
                         // Columns have a fixed height
                         height = pAttrs->GetSize().Height();
@@ -920,6 +927,12 @@ void SwPageFrame::MakeAll(vcl::RenderContext* 
pRenderContext)
                     {
                         // No need for borders.
                         height = GetContentHeight(0, 0);
+                        if (height > nFullBodyHeight)
+                        {
+                            // Content height would be larger than the 
show-whitespace body height,
+                            // limit it.
+                            height = nFullBodyHeight;
+                        }
                     }
 
                     if (height > 0)
diff --git a/sw/source/core/layout/pagechg.cxx 
b/sw/source/core/layout/pagechg.cxx
index d086166caaef..1c49d6d2b8e5 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -65,6 +65,7 @@
 #include <sortedobjs.hxx>
 #include <calbck.hxx>
 #include <txtfly.hxx>
+#include <frmatr.hxx>
 
 using namespace ::com::sun::star;
 
@@ -2561,7 +2562,10 @@ bool 
SwPageFrame::CheckPageHeightValidForHideWhitespace(SwTwips nDiff)
             // Content frame doesn't fit the actual size, check if it fits the 
nominal one.
             const SwFrameFormat* pPageFormat = static_cast<const 
SwFrameFormat*>(GetDep());
             const Size& rPageSize = pPageFormat->GetFrameSize().GetSize();
-            tools::Long nWhitespace = rPageSize.getHeight() - 
getFrameArea().Height();
+            // Count what would be the max size for the body frame, ignoring 
top/bottom margin.
+            const SvxULSpaceItem& rULSpace = pPageFormat->GetULSpace();
+            SwTwips nNominalHeight = rPageSize.getHeight() - 
rULSpace.GetUpper() - rULSpace.GetLower();
+            tools::Long nWhitespace = nNominalHeight - getFrameArea().Height();
             if (nWhitespace > -nDiff)
             {
                 // It does: don't move it and invalidate our page frame so

Reply via email to