sw/inc/crsrsh.hxx                                                 |    4 
 sw/inc/ndarr.hxx                                                  |    9 
 sw/inc/node.hxx                                                   |    2 
 sw/qa/extras/layout/data/largeTopMarginAndHiddenFirstSection.fodt |   15 +
 sw/qa/extras/layout/data/pageBreakInHiddenSection.fodt            |   90 
+++++++
 sw/qa/extras/layout/layout.cxx                                    |   27 +-
 sw/qa/extras/layout/layout2.cxx                                   |   40 +++
 sw/qa/extras/uiwriter/data/FrameInHiddenSection.fodt              |   20 +
 sw/qa/extras/uiwriter/data/hiddenSectionsAroundPageBreak.fodt     |   21 +
 sw/qa/extras/uiwriter/uiwriter8.cxx                               |   41 +++
 sw/source/core/crsr/crsrsh.cxx                                    |   21 +
 sw/source/core/crsr/pam.cxx                                       |    5 
 sw/source/core/crsr/swcrsr.cxx                                    |    4 
 sw/source/core/doc/docedt.cxx                                     |    4 
 sw/source/core/docnode/ndsect.cxx                                 |    4 
 sw/source/core/docnode/nodes.cxx                                  |   58 +++-
 sw/source/core/docnode/section.cxx                                |    7 
 sw/source/core/edit/editsh.cxx                                    |    2 
 sw/source/core/inc/frame.hxx                                      |    2 
 sw/source/core/inc/sectfrm.hxx                                    |    2 
 sw/source/core/inc/txtfrm.hxx                                     |    2 
 sw/source/core/layout/calcmove.cxx                                |   13 -
 sw/source/core/layout/findfrm.cxx                                 |    8 
 sw/source/core/layout/flowfrm.cxx                                 |  119 
++++------
 sw/source/core/layout/frmtool.cxx                                 |   23 -
 sw/source/core/layout/ftnfrm.cxx                                  |   10 
 sw/source/core/layout/pagechg.cxx                                 |    5 
 sw/source/core/layout/sectfrm.cxx                                 |   37 +++
 sw/source/core/layout/trvlfrm.cxx                                 |   25 +-
 sw/source/core/text/txtfrm.cxx                                    |   19 -
 30 files changed, 466 insertions(+), 173 deletions(-)

New commits:
commit c6a9156a8e58c207ce0201db9f4f5facf1a5f8d4
Author:     Mike Kaganski <[email protected]>
AuthorDate: Wed Feb 14 19:22:42 2024 +0600
Commit:     Mike Kaganski <[email protected]>
CommitDate: Tue Feb 20 15:27:36 2024 +0600

    tdf#159565: make sure to handle leading hidden section correctly
    
    Change-Id: I41c7d2b6e765f03c72a968fd05e8de7047f1ce41
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163371
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163478
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index e63f6b786a53..a35d6e3b51c6 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -333,7 +333,7 @@ public:
     void ExtendedSelectAll(bool bFootnotes = true);
     /// If ExtendedSelectAll() was called and selection didn't change since 
then.
     ::std::optional<::std::pair<SwNode const*, ::std::vector<SwTableNode*>>> 
ExtendedSelectedAll() const;
-    enum class StartsWith { None, Table, HiddenPara };
+    enum class StartsWith { None, Table, HiddenPara, HiddenSection };
     /// If document body starts with a table or starts/ends with hidden 
paragraph.
     StartsWith StartsWith_();
 
diff --git a/sw/inc/ndarr.hxx b/sw/inc/ndarr.hxx
index b7fd0bb2e078..a4f9e37a7631 100644
--- a/sw/inc/ndarr.hxx
+++ b/sw/inc/ndarr.hxx
@@ -131,6 +131,11 @@ class SW_DLLPUBLIC SwNodes final
 
     SwNodes(SwDoc& rDoc);
 
+    // Returns start of the document section 
(PostIts/Inserts/Autotext/Redlines/Content),
+    // or of a specific fly / header / footer / footnote, where this node is, 
which must not
+    // be crossed when moving backwards
+    SwNodeOffset StartOfGlobalSection(const SwNode& node) const;
+
 public:
     ~SwNodes();
 
@@ -188,8 +193,8 @@ public:
 
     SwContentNode* GoNext(SwNodeIndex *) const;
     SwContentNode* GoNext(SwPosition *) const;
-    static SwContentNode* GoPrevious(SwNodeIndex *);
-    static SwContentNode* GoPrevious(SwPosition *);
+    static SwContentNode* GoPrevious(SwNodeIndex *, bool canCrossBoundary = 
false);
+    static SwContentNode* GoPrevious(SwPosition *, bool canCrossBoundary = 
false);
 
     /** Go to next content-node that is not protected or hidden
        (Both set FALSE ==> GoNext/GoPrevious!!!). */
diff --git a/sw/qa/extras/uiwriter/data/FrameInHiddenSection.fodt 
b/sw/qa/extras/uiwriter/data/FrameInHiddenSection.fodt
new file mode 100644
index 000000000000..2095c7173046
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/FrameInHiddenSection.fodt
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:body>
+  <office:text>
+   <text:section text:name="Section1">
+    <text:section text:name="Section2Hidden" text:display="none">
+     <text:p><draw:frame text:anchor-type="paragraph" svg:x="1cm" svg:y="1cm" 
svg:width="1cm">
+      <draw:text-box/>
+     </draw:frame>lorem</text:p>
+    </text:section>
+    <text:section text:name="Section3"/>
+    <text:section text:name="Section4"/>
+    <text:section text:name="Section5">
+     <text:p>ipsum</text:p>
+    </text:section>
+   </text:section>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx 
b/sw/qa/extras/uiwriter/uiwriter8.cxx
index 50c34b94d25b..30641859980e 100644
--- a/sw/qa/extras/uiwriter/uiwriter8.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -18,6 +18,8 @@
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
 #include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+
 #include <comphelper/propertysequence.hxx>
 #include <boost/property_tree/json_parser.hpp>
 #include <frameformats.hxx>
@@ -2653,6 +2655,28 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, 
testHiddenSectionsAroundPageBreak)
     CPPUNIT_ASSERT_EQUAL(OUString("Landscape"), getProperty<OUString>(xCursor, 
"PageStyleName"));
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf159565)
+{
+    // Given a document with a hidden section in the beginning, additionally 
containing a frame
+    createSwDoc("FrameInHiddenSection.fodt");
+
+    dispatchCommand(mxComponent, u".uno:SelectAll", {});
+
+    // Check that the selection covers the whole visible text
+    uno::Reference<css::frame::XModel> xModel(mxComponent, 
uno::UNO_QUERY_THROW);
+    uno::Reference<css::view::XSelectionSupplier> 
xSelSupplier(xModel->getCurrentController(),
+                                                               
uno::UNO_QUERY_THROW);
+    uno::Reference<css::container::XIndexAccess> 
xSelections(xSelSupplier->getSelection(),
+                                                             
uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSelections->getCount());
+    uno::Reference<css::text::XTextRange> 
xSelection(xSelections->getByIndex(0),
+                                                     uno::UNO_QUERY_THROW);
+
+    // Without the fix, this would fail - there was no selection
+    CPPUNIT_ASSERT_EQUAL(OUString("" SAL_NEWLINE_STRING SAL_NEWLINE_STRING 
"ipsum"),
+                         xSelection->getString());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index f20dc50a6b7e..a97e06cc051f 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -768,6 +768,8 @@ static typename SwCursorShell::StartsWith 
StartsWith(SwStartNode const& rStart)
         switch (rNode.GetNodeType())
         {
             case SwNodeType::Section:
+                if (rNode.GetSectionNode()->GetSection().IsHidden())
+                    return SwCursorShell::StartsWith::HiddenSection;
                 continue;
             case SwNodeType::Table:
                 return SwCursorShell::StartsWith::Table;
@@ -792,11 +794,16 @@ static typename SwCursorShell::StartsWith 
EndsWith(SwStartNode const& rStart)
         switch (rNode.GetNodeType())
         {
             case SwNodeType::End:
-                if (rNode.StartOfSectionNode()->IsTableNode())
+                if (auto pStartNode = rNode.StartOfSectionNode(); 
pStartNode->IsTableNode())
                 {
                     return SwCursorShell::StartsWith::Table;
                 }
-//TODO buggy SwUndoRedline in testTdf137503?                
assert(rNode.StartOfSectionNode()->IsSectionNode());
+                else if (pStartNode->IsSectionNode())
+                {
+                    if (pStartNode->GetSectionNode()->GetSection().IsHidden())
+                        return SwCursorShell::StartsWith::HiddenSection;
+                }
+                    //TODO buggy SwUndoRedline in testTdf137503?               
 assert(rNode.StartOfSectionNode()->IsSectionNode());
             break;
             case SwNodeType::Text:
                 if (rNode.GetTextNode()->IsHidden())
@@ -3418,7 +3425,7 @@ bool SwCursorShell::FindValidContentNode( bool bOnlyText )
         GetDoc()->GetDocShell()->IsReadOnlyUI() )
         return true;
 
-    if( m_pCurrentCursor->HasMark() )
+    if( m_pCurrentCursor->HasMark() && !mbSelectAll )
         ClearMark();
 
     // first check for frames
diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index e3bb1a02c8d8..4e0a8753e71e 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -899,7 +899,7 @@ static bool lcl_MakeSelFwrd( const SwNode& rSttNd, const 
SwNode& rEndNd,
 
     rPam.SetMark();
     rPam.GetPoint()->Assign(rEndNd);
-    pCNd = SwNodes::GoPrevious( rPam.GetPoint() );
+    pCNd = SwNodes::GoPrevious(rPam.GetPoint(), true);
     if( !pCNd )
         return false;
     rPam.GetPoint()->AssignEndIndex(*pCNd);
@@ -919,7 +919,7 @@ static bool lcl_MakeSelBkwrd( const SwNode& rSttNd, const 
SwNode& rEndNd,
     if( !bFirst )
     {
         rPam.GetPoint()->Assign(rSttNd);
-        pCNd = SwNodes::GoPrevious( rPam.GetPoint() );
+        pCNd = SwNodes::GoPrevious(rPam.GetPoint(), true);
         if( !pCNd )
             return false;
         rPam.GetPoint()->AssignEndIndex(*pCNd);
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index 496ab82b32fd..90d7466c7026 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -1325,34 +1325,68 @@ SwContentNode* SwNodes::GoNext(SwPosition *pIdx) const
     return static_cast<SwContentNode*>(pNd);
 }
 
-SwContentNode* SwNodes::GoPrevious(SwNodeIndex *pIdx)
+SwNodeOffset SwNodes::StartOfGlobalSection(const SwNode& node) const
+{
+    const SwNodeOffset pos = node.GetIndex();
+    if (GetEndOfExtras().GetIndex() < pos)
+        // Regular ContentSection
+        return GetEndOfExtras().GetIndex() + SwNodeOffset(1);
+    if (GetEndOfAutotext().GetIndex() < pos)
+        // Redlines
+        return GetEndOfAutotext().GetIndex() + SwNodeOffset(1);
+    if (GetEndOfInserts().GetIndex() < pos)
+    {
+        // Flys/Headers/Footers
+        if (auto* p = node.FindFlyStartNode())
+            return p->GetIndex();
+        if (auto* p = node.FindHeaderStartNode())
+            return p->GetIndex();
+        if (auto* p = node.FindFooterStartNode())
+            return p->GetIndex();
+        return GetEndOfInserts().GetIndex() + SwNodeOffset(1);
+    }
+    if (GetEndOfPostIts().GetIndex() < pos)
+    {
+        // Footnotes
+        if (auto* p = node.FindFootnoteStartNode())
+            return p->GetIndex();
+        return GetEndOfPostIts().GetIndex() + SwNodeOffset(1);
+    }
+    return SwNodeOffset(0);
+}
+
+SwContentNode* SwNodes::GoPrevious(SwNodeIndex* pIdx, bool canCrossBoundary)
 {
     if( !pIdx->GetIndex() )
         return nullptr;
 
     SwNodeIndex aTmp( *pIdx, -1 );
+    SwNodeOffset aGlobalStart(
+        canCrossBoundary ? SwNodeOffset(0) : 
aTmp.GetNodes().StartOfGlobalSection(pIdx->GetNode()));
     SwNode* pNd = nullptr;
-    while( aTmp.GetIndex() && !( pNd = &aTmp.GetNode())->IsContentNode() )
+    while (aTmp > aGlobalStart && !(pNd = &aTmp.GetNode())->IsContentNode())
         --aTmp;
 
-    if( !aTmp.GetIndex() )
+    if (aTmp <= aGlobalStart)
         pNd = nullptr;
     else
         (*pIdx) = aTmp;
     return static_cast<SwContentNode*>(pNd);
 }
 
-SwContentNode* SwNodes::GoPrevious(SwPosition *pIdx)
+SwContentNode* SwNodes::GoPrevious(SwPosition* pIdx, bool canCrossBoundary)
 {
     if( !pIdx->GetNodeIndex() )
         return nullptr;
 
     SwNodeIndex aTmp( pIdx->GetNode(), -1 );
+    SwNodeOffset aGlobalStart(
+        canCrossBoundary ? SwNodeOffset(0) : 
aTmp.GetNodes().StartOfGlobalSection(pIdx->GetNode()));
     SwNode* pNd = nullptr;
-    while( aTmp.GetIndex() && !( pNd = &aTmp.GetNode())->IsContentNode() )
+    while( aTmp > aGlobalStart && !( pNd = &aTmp.GetNode())->IsContentNode() )
         --aTmp;
 
-    if( !aTmp.GetIndex() )
+    if (aTmp <= aGlobalStart)
         pNd = nullptr;
     else
         pIdx->Assign(aTmp);
@@ -2061,8 +2095,9 @@ SwContentNode* SwNodes::GoPrevSection( SwNodeIndex * pIdx,
 {
     bool bFirst = true;
     SwNodeIndex aTmp( *pIdx );
+    SwNodeOffset 
aGlobalStart(aTmp.GetNodes().StartOfGlobalSection(pIdx->GetNode()));
     const SwNode* pNd;
-    while( aTmp > SwNodeOffset(0) )
+    while (aTmp > aGlobalStart)
     {
         pNd = & aTmp.GetNode();
         if (SwNodeType::End == pNd->GetNodeType())
@@ -2118,8 +2153,9 @@ SwContentNode* SwNodes::GoPrevSection( SwPosition * pIdx,
 {
     bool bFirst = true;
     SwNodeIndex aTmp( pIdx->GetNode() );
+    SwNodeOffset 
aGlobalStart(aTmp.GetNodes().StartOfGlobalSection(pIdx->GetNode()));
     const SwNode* pNd;
-    while( aTmp > SwNodeOffset(0) )
+    while (aTmp > aGlobalStart)
     {
         pNd = & aTmp.GetNode();
         if (SwNodeType::End == pNd->GetNodeType())
commit 0194a637a473ede5952fca6df51f25bd00cf95ad
Author:     Mike Kaganski <[email protected]>
AuthorDate: Fri Feb 9 11:56:19 2024 +0600
Commit:     Mike Kaganski <[email protected]>
CommitDate: Tue Feb 20 14:53:20 2024 +0600

    tdf#159565 prerequisite: make hidden sections have zero-height frames
    
    As mentioned in commit bb733957dd39e6f0b9d80bb59eb0177188794797 (tdf#114973
    sw: enable SelectAll with hidden para at start/end, 2023-01-27), the hidden
    sections didn't have frames. That prevented correct handling of the case
    when such a frame was in the beginning of the document.
    
    This change re-implements the hidden section to use 0-height frames, like
    hidden paragraphs, as a pre-requisite for a follow-up change.
    
    Some layout breakages noticed while working on this are unit-tested now.
    
    This change needed to handle the case when the first section is hidden, and
    then goes a page break with page style. In this case, the page style must
    apply to the very first page of the document. Implementing this now, when
    the frame that defines the page style is not the first in the document, I
    accidentally fixed also the previously broken case when the first paragraph
    was hidden. Now the page style defined in the second paragraph's page break
    will apply correctly.
    
    This change makes hidden sections break outer section's frames. This means
    that when text borders are shown, there will be an artifact in the place of
    the hidden sections (a horizontal line breaking outer frame). I suppose
    it's not a problem, actually helping to see the layout better, so in line
    with the "show text borders" helper functionality. If this proves to be
    problematic, this can be handled specially in a follow-up.
    
    Change-Id: I14ebf0559b463186aba28902cd10c5cc978ba456
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163151
    Tested-by: Mike Kaganski <[email protected]>
    Reviewed-by: Mike Kaganski <[email protected]>
    Signed-off-by: Xisco Fauli <[email protected]>

diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 47b83ce1ffb3..e63f6b786a53 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -266,7 +266,7 @@ private:
     SAL_DLLPRIVATE bool LRMargin( bool, bool bAPI = false );
     SAL_DLLPRIVATE bool IsAtLRMargin( bool, bool bAPI = false ) const;
 
-    SAL_DLLPRIVATE bool isInHiddenTextFrame(SwShellCursor* pShellCursor);
+    SAL_DLLPRIVATE bool isInHiddenFrame(SwShellCursor* pShellCursor);
 
     SAL_DLLPRIVATE bool GoStartWordImpl();
     SAL_DLLPRIVATE bool GoEndWordImpl();
diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx
index 8bed9dd7240d..ed4013f74057 100644
--- a/sw/inc/node.hxx
+++ b/sw/inc/node.hxx
@@ -588,7 +588,7 @@ public:
     const SwSection& GetSection() const { return *m_pSection; }
           SwSection& GetSection()       { return *m_pSection; }
 
-    SwFrame *MakeFrame( SwFrame* );
+    SwFrame* MakeFrame(SwFrame* pSib, bool bHidden);
 
     /** Creates the frms for the SectionNode (i.e. the SectionFrames).
        On default the frames are created until the end of the range.
diff --git a/sw/qa/extras/layout/data/largeTopMarginAndHiddenFirstSection.fodt 
b/sw/qa/extras/layout/data/largeTopMarginAndHiddenFirstSection.fodt
new file mode 100644
index 000000000000..fbefc5c48046
--- /dev/null
+++ b/sw/qa/extras/layout/data/largeTopMarginAndHiddenFirstSection.fodt
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:styles>
+  <style:style style:name="Standard" style:family="paragraph" 
style:class="text">
+   <style:paragraph-properties fo:margin-top="1in" fo:margin-bottom="0" 
style:contextual-spacing="false" fo:line-height="12pt"/>
+  </style:style>
+ </office:styles>
+ <office:body>
+  <office:text>
+   <text:section text:name="Hidden" text:display="none"/>
+   <text:section text:name="Shown"/>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/layout/data/pageBreakInHiddenSection.fodt 
b/sw/qa/extras/layout/data/pageBreakInHiddenSection.fodt
new file mode 100644
index 000000000000..5fae6a491704
--- /dev/null
+++ b/sw/qa/extras/layout/data/pageBreakInHiddenSection.fodt
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:master-page-name="Landscape">
+   <style:paragraph-properties style:page-number="1"/>
+  </style:style>
+  <style:style style:name="P2" style:family="paragraph" 
style:master-page-name="Landscape">
+   <style:paragraph-properties style:page-number="1"/>
+   <style:text-properties text:display="none"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:p>First line</text:p>
+   <text:section text:name="Hidden" text:display="none">
+    <text:p text:style-name="P1"/>
+   </text:section>
+   <text:section text:name="Shown">
+    <text:p>Before break (still first page)</text:p>
+   </text:section>
+   <text:section text:name="HiddenText">
+    <text:p text:style-name="P2"/>
+   </text:section>
+   <text:p>After break</text:p>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p/>
+   <text:p>Should be together with next</text:p>
+   <text:section text:name="Hidden2" text:display="none">
+    <text:p text:style-name="P2"/>
+   </text:section>
+   <text:p>Should be together with previous</text:p>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 0ffdb543fbd9..f3f165b3cd41 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -3632,13 +3632,26 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf119875)
 {
     createSwDoc("tdf119875.odt");
     xmlDocUniquePtr pXmlDoc = parseLayoutDump();
-    sal_Int32 nFirstTop
-        = getXPath(pXmlDoc, "/root/page[2]/body/section[1]/infos/bounds", 
"top").toInt32();
-    sal_Int32 nSecondTop
-        = getXPath(pXmlDoc, "/root/page[2]/body/section[2]/infos/bounds", 
"top").toInt32();
-    // The first section had the same top value as the second one, so they
-    // overlapped.
-    CPPUNIT_ASSERT_LESS(nSecondTop, nFirstTop);
+
+    // formatName is yet unavailable in 7.5 branch, commented out in backport
+    // assertXPath(pXmlDoc, "//page[2]/body/section[1]", "formatName", u"S10");
+    // assertXPath(pXmlDoc, "//page[2]/body/section[2]", "formatName", u"S11");
+    // assertXPath(pXmlDoc, "//page[2]/body/section[3]", "formatName", u"S13");
+    // assertXPath(pXmlDoc, "//page[2]/body/section[4]", "formatName", u"S14");
+    // Sections "S10" and "S13" are hidden -> their frames are zero-height
+    assertXPath(pXmlDoc, "//page[2]/body/section[1]/infos/bounds", "height", 
u"0");
+    assertXPath(pXmlDoc, "//page[2]/body/section[3]/infos/bounds", "height", 
u"0");
+
+    OUString S10Top = getXPath(pXmlDoc, 
"//page[2]/body/section[1]/infos/bounds", "top");
+    OUString S11Top = getXPath(pXmlDoc, 
"//page[2]/body/section[2]/infos/bounds", "top");
+    OUString S13Top = getXPath(pXmlDoc, 
"//page[2]/body/section[3]/infos/bounds", "top");
+    OUString S14Top = getXPath(pXmlDoc, 
"//page[2]/body/section[4]/infos/bounds", "top");
+
+    CPPUNIT_ASSERT_EQUAL(S10Top, S11Top);
+    CPPUNIT_ASSERT_EQUAL(S13Top, S14Top);
+
+    // Section "S11" had the same top value as section "S14", so they 
overlapped.
+    CPPUNIT_ASSERT_LESS(S14Top.toInt32(), S11Top.toInt32());
 }
 
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf120287)
diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx
index a29664cf8a13..61404c658e84 100644
--- a/sw/qa/extras/layout/layout2.cxx
+++ b/sw/qa/extras/layout/layout2.cxx
@@ -2919,6 +2919,46 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf156725)
                 
"/root/page[2]/body/txt/anchored/fly/column[2]/body/section/column[2]/body/txt",
 1);
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testLargeTopParaMarginAfterHiddenSection)
+{
+    // Given a large top margin in Standard paragraph style, and the first 
section hidden
+    createSwDoc("largeTopMarginAndHiddenFirstSection.fodt");
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    // Make sure there is only one page and two sections, first hidden 
(zero-height)
+    assertXPath(pXmlDoc, "//page", 1);
+    assertXPath(pXmlDoc, "//page/body/section", 2);
+    assertXPath(pXmlDoc, "//page/body/section[1]/infos/bounds", "height", 
u"0");
+    // Check that the top margin (1 in = 1440 twip) is added to line height 
(12 pt = 240 twip)
+    assertXPath(pXmlDoc, "//page/body/section[2]/infos/bounds", "height", 
u"1680");
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testPageBreakInHiddenSection)
+{
+    // Given a paragraph with page-break-before with page style and page number
+    createSwDoc("pageBreakInHiddenSection.fodt");
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "//page", 4);
+    assertXPath(pXmlDoc, "//section", 4);
+    assertXPath(pXmlDoc, "//page[1]/body/txt", 1);
+    // The page break inside the hidden section is ignored (otherwise, there 
would be one section
+    // on the first page)
+    assertXPath(pXmlDoc, "//page[1]/body/section", 2);
+    // The first section is hidden
+    assertXPath(pXmlDoc, "//page[1]/body/section[1]/infos/bounds", "height", 
u"0");
+
+    // Page 2 is empty even page (generated by the next page's section with 
page-break-before)
+    assertXPath(pXmlDoc, "//page[2]/body", 0);
+
+    // The section on page 3 is not hidden, only text in it is, therefore its 
page break works
+    assertXPath(pXmlDoc, "//page[3]/body/section", 1);
+    assertXPath(pXmlDoc, "//page[3]/body/section/infos/bounds", "height", 
u"0");
+
+    // The section on page 4 is hidden, thus page break in it is ignored (no 
further pages, where
+    // the section would be moved to otherwise)
+    assertXPath(pXmlDoc, "//page[4]/body/section", 1);
+    assertXPath(pXmlDoc, "//page[4]/body/section/infos/bounds", "height", 
u"0");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/uiwriter/data/hiddenSectionsAroundPageBreak.fodt 
b/sw/qa/extras/uiwriter/data/hiddenSectionsAroundPageBreak.fodt
new file mode 100644
index 000000000000..12761847ed75
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/hiddenSectionsAroundPageBreak.fodt
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:master-page-name="Landscape">
+   <style:paragraph-properties style:page-number="auto" 
fo:break-before="page"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:section text:name="Section 1" text:display="none"/>
+   <text:section text:name="Section 2">
+    <text:p text:style-name="P1">A paragraph with a page-break-before</text:p>
+   </text:section>
+   <text:section text:name="Section 3" text:display="none"/>
+   <text:section text:name="Section 4">
+    <text:p>Lorem</text:p>
+   </text:section>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx 
b/sw/qa/extras/uiwriter/uiwriter8.cxx
index fd154c6c36a2..50c34b94d25b 100644
--- a/sw/qa/extras/uiwriter/uiwriter8.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -2636,6 +2636,23 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf73483)
     assertXPath(pXml, para_style_path, "master-page-name", "Right_20_Page");
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testHiddenSectionsAroundPageBreak)
+{
+    createSwDoc("hiddenSectionsAroundPageBreak.fodt");
+
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY_THROW);
+    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+        xModel->getCurrentController(), uno::UNO_QUERY_THROW);
+    uno::Reference<text::XPageCursor> 
xCursor(xTextViewCursorSupplier->getViewCursor(),
+                                              uno::UNO_QUERY_THROW);
+
+    // Make sure that the page style is set correctly
+    xCursor->jumpToFirstPage();
+    CPPUNIT_ASSERT_EQUAL(OUString("Landscape"), getProperty<OUString>(xCursor, 
"PageStyleName"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 49a6e7aaff4d..f20dc50a6b7e 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -937,14 +937,14 @@ bool SwCursorShell::MovePage( SwWhichPage fnWhichPage, 
SwPosPage fnPosPage )
     return bRet;
 }
 
-bool SwCursorShell::isInHiddenTextFrame(SwShellCursor* pShellCursor)
+bool SwCursorShell::isInHiddenFrame(SwShellCursor* pShellCursor)
 {
     SwContentNode *pCNode = pShellCursor->GetPointContentNode();
     std::pair<Point, bool> tmp(pShellCursor->GetPtPos(), false);
     SwContentFrame *const pFrame = pCNode
         ? pCNode->getLayoutFrame(GetLayout(), pShellCursor->GetPoint(), &tmp)
         : nullptr;
-    return !pFrame || (pFrame->IsTextFrame() && 
static_cast<SwTextFrame*>(pFrame)->IsHiddenNow());
+    return !pFrame || pFrame->IsHiddenNow();
 }
 
 // sw_redlinehide: this should work for all cases: GoCurrPara, GoNextPara, 
GoPrevPara
@@ -985,7 +985,7 @@ bool SwCursorShell::MovePara(SwWhichPara fnWhichPara, 
SwMoveFnCollection const &
         //which is what SwCursorShell::UpdateCursorPos will reset
         //the position to if we pass it a position in an
         //invisible hidden paragraph field
-        while (isInHiddenTextFrame(pTmpCursor)
+        while (isInHiddenFrame(pTmpCursor)
                 || !IsAtStartOrEndOfFrame(this, pTmpCursor, fnPosPara))
         {
             if (!pTmpCursor->MovePara(fnWhichPara, fnPosPara))
@@ -1775,7 +1775,7 @@ void SwCursorShell::UpdateCursorPos()
     SwShellCursor* pShellCursor = getShellCursor( true );
     Size aOldSz( GetDocSize() );
 
-    if (isInHiddenTextFrame(pShellCursor) && !ExtendedSelectedAll())
+    if (isInHiddenFrame(pShellCursor) && !ExtendedSelectedAll())
     {
         SwCursorMoveState aTmpState(CursorMoveState::SetOnlyText);
         aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx
index bc3f9d7104a2..f98143ab4ff1 100644
--- a/sw/source/core/crsr/pam.cxx
+++ b/sw/source/core/crsr/pam.cxx
@@ -1037,7 +1037,7 @@ SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, 
SwMoveFnCollection const &
                     (
                         nullptr == pFrame ||
                         ( !bInReadOnly && pFrame->IsProtected() ) ||
-                        (pFrame->IsTextFrame() && static_cast<SwTextFrame 
const*>(pFrame)->IsHiddenNow())
+                        pFrame->IsHiddenNow()
                     ) ||
                     ( !bInReadOnly && pNd->FindSectionNode() &&
                         pNd->FindSectionNode()->GetSection().IsProtect()
@@ -1078,8 +1078,7 @@ SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, 
SwMoveFnCollection const &
                         SwContentFrame const*const 
pFrame(pNd->getLayoutFrame(pLayout));
                         if (nullptr == pFrame ||
                             ( !bInReadOnly && pFrame->IsProtected() ) ||
-                            ( pFrame->IsTextFrame() &&
-                                static_cast<SwTextFrame 
const*>(pFrame)->IsHiddenNow()))
+                            pFrame->IsHiddenNow())
                         {
                             pNd = nullptr;
                             continue;
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index 021e100efdc7..7cac33d63e70 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -553,7 +553,7 @@ uno::Any SwDoc::Spell( SwPaM& rPaM,
                     {
                         nCurrNd = pNd->EndOfSectionIndex();
                     }
-                    else if( 
!static_cast<SwTextFrame*>(pContentFrame)->IsHiddenNow() )
+                    else if( !pContentFrame->IsHiddenNow() )
                     {
                         if( pPageCnt && *pPageCnt && pPageSt )
                         {
@@ -766,7 +766,7 @@ static bool lcl_HyphenateNode( SwNode* pNd, void* pArgs )
         // sw_redlinehide: this will be called once per node for merged nodes;
         // the fully deleted ones won't have frames so are skipped.
         SwContentFrame* pContentFrame = pNode->getLayoutFrame( 
pNode->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout() );
-        if( pContentFrame && 
!static_cast<SwTextFrame*>(pContentFrame)->IsHiddenNow() )
+        if( pContentFrame && !pContentFrame->IsHiddenNow() )
         {
             sal_uInt16 *pPageSt = pHyphArgs->GetPageSt();
             sal_uInt16 *pPageCnt = pHyphArgs->GetPageCnt();
diff --git a/sw/source/core/docnode/ndsect.cxx 
b/sw/source/core/docnode/ndsect.cxx
index f4fe9b9a3ec4..6b04f6504fb5 100644
--- a/sw/source/core/docnode/ndsect.cxx
+++ b/sw/source/core/docnode/ndsect.cxx
@@ -1028,9 +1028,9 @@ SwSectionNode::~SwSectionNode()
     }
 }
 
-SwFrame *SwSectionNode::MakeFrame( SwFrame *pSib )
+SwFrame* SwSectionNode::MakeFrame(SwFrame* pSib, bool bHidden)
 {
-    m_pSection->m_Data.SetHiddenFlag(false);
+    m_pSection->m_Data.SetHiddenFlag(bHidden);
     return new SwSectionFrame( *m_pSection, pSib );
 }
 
diff --git a/sw/source/core/docnode/nodes.cxx b/sw/source/core/docnode/nodes.cxx
index afef83e76df5..496ab82b32fd 100644
--- a/sw/source/core/docnode/nodes.cxx
+++ b/sw/source/core/docnode/nodes.cxx
@@ -1952,7 +1952,7 @@ SwContentNode* SwNodes::GoNextSection( SwNodeIndex * pIdx,
         if (SwNodeType::Section == pNd->GetNodeType())
         {
             const SwSection& rSect = static_cast<const 
SwSectionNode*>(pNd)->GetSection();
-            if( (bSkipHidden && rSect.IsHiddenFlag()) ||
+            if( (bSkipHidden && rSect.CalcHiddenFlag()) ||
                 (bSkipProtect && rSect.IsProtectFlag()) )
                 // than skip the section
                 aTmp = *pNd->EndOfSectionNode();
@@ -1963,7 +1963,7 @@ SwContentNode* SwNodes::GoNextSection( SwNodeIndex * pIdx,
             {
                 const SwSection& rSect = static_cast<SwSectionNode*>(pNd->
                                 m_pStartOfSection)->GetSection();
-                if( (bSkipHidden && rSect.IsHiddenFlag()) ||
+                if( (bSkipHidden && rSect.CalcHiddenFlag()) ||
                     (bSkipProtect && rSect.IsProtectFlag()) )
                     // than skip the section
                     aTmp = *pNd->EndOfSectionNode();
@@ -1974,7 +1974,7 @@ SwContentNode* SwNodes::GoNextSection( SwNodeIndex * pIdx,
             const SwSectionNode* pSectNd;
             if( ( bSkipHidden || bSkipProtect ) &&
                 nullptr != (pSectNd = pNd->FindSectionNode() ) &&
-                ( ( bSkipHidden && pSectNd->GetSection().IsHiddenFlag() ) ||
+                ( ( bSkipHidden && pSectNd->GetSection().CalcHiddenFlag() ) ||
                   ( bSkipProtect && pSectNd->GetSection().IsProtectFlag() )) )
             {
                 aTmp = *pSectNd->EndOfSectionNode();
diff --git a/sw/source/core/docnode/section.cxx 
b/sw/source/core/docnode/section.cxx
index a92694e5b58f..32cbf6dcd811 100644
--- a/sw/source/core/docnode/section.cxx
+++ b/sw/source/core/docnode/section.cxx
@@ -291,14 +291,11 @@ void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, 
bool const bCondition)
             // Tell all Children that they are hidden
             const sw::SectionHidden aHint;
             pFormat->CallSwClientNotify(aHint);
-
-            // Delete all Frames
-            pFormat->DelFrames();
         }
     }
     else if (m_Data.IsHiddenFlag()) // show Nodes again
     {
-        // Show all Frames (Child Sections are accounted for by MakeFrames)
+        // Show all Frames
         // Only if the Parent Section is not restricting us!
         SwSection* pParentSect = pFormat->GetParentSection();
         if( !pParentSect || !pParentSect->IsHiddenFlag() )
@@ -306,8 +303,6 @@ void SwSection::ImplSetHiddenFlag(bool const bTmpHidden, 
bool const bCondition)
             // Tell all Children that the Parent is not hidden anymore
             const sw::SectionHidden aHint(false);
             pFormat->CallSwClientNotify(aHint);
-
-            pFormat->MakeFrames();
         }
     }
 }
diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx
index 6803f31bc13f..2d07c4fa536a 100644
--- a/sw/source/core/edit/editsh.cxx
+++ b/sw/source/core/edit/editsh.cxx
@@ -796,7 +796,7 @@ void SwEditShell::SetNumberingRestart()
                     if( nullptr != pContentFrame )
                     {
                         // skip hidden frames - ignore protection!
-                        if( 
!static_cast<SwTextFrame*>(pContentFrame)->IsHiddenNow() )
+                        if( !pContentFrame->IsHiddenNow() )
                         {
                             // if the node is numbered and the starting value 
of the numbering equals the
                             // start value of the numbering rule then set this 
value as hard starting value
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index e5b4c4c9bf5c..b3f3adc09c32 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -883,6 +883,8 @@ public:
     // Fly in ... and footnotes
     bool IsProtected() const;
 
+    virtual bool IsHiddenNow() const;
+
     bool IsColLocked()  const { return mbColLocked; }
     virtual bool IsDeleteForbidden() const { return mnForbidDelete > 0; }
 
diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx
index e08a9b0a7137..3ea6a5678ffc 100644
--- a/sw/source/core/inc/sectfrm.hxx
+++ b/sw/source/core/inc/sectfrm.hxx
@@ -88,6 +88,8 @@ public:
     virtual void Cut() override;
     virtual void Paste( SwFrame* pParent, SwFrame* pSibling = nullptr ) 
override;
 
+    virtual bool IsHiddenNow() const override;
+
     inline const SwSectionFrame *GetFollow() const;
     inline       SwSectionFrame *GetFollow();
     SwSectionFrame* FindMaster() const;
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 3fd73ea2c6ec..cfafca754370 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -548,7 +548,7 @@ public:
 #endif
 
     /// Hidden
-    bool IsHiddenNow() const;       // bHidden && pOut == pPrt
+    virtual bool IsHiddenNow() const override; // bHidden && pOut == pPrt
     void HideHidden();              // Remove appendage if Hidden
     void HideFootnotes(TextFrameIndex nStart, TextFrameIndex nEnd);
 
diff --git a/sw/source/core/layout/calcmove.cxx 
b/sw/source/core/layout/calcmove.cxx
index 73b72d03305c..ce74dd73e891 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -164,7 +164,7 @@ bool SwContentFrame::ShouldBwdMoved( SwLayoutFrame 
*pNewUpper, bool & )
 
             if ( nMoveAnyway < 3 )
             {
-                if ( nSpace )
+                if (nSpace || IsHiddenNow())
                 {
                     // Do not notify footnotes which are stuck to the 
paragraph:
                     // This would require extremely confusing code, taking into
@@ -196,7 +196,7 @@ bool SwContentFrame::ShouldBwdMoved( SwLayoutFrame 
*pNewUpper, bool & )
             }
 
             // Check for space left in new upper
-            return nSpace != 0;
+            return nSpace != 0 || IsHiddenNow();
         }
     }
     return false;
@@ -519,7 +519,7 @@ static SwFrame* lcl_NotHiddenPrev( SwFrame* pFrame )
     do
     {
         pRet = lcl_Prev( pRet );
-    } while ( pRet && pRet->IsTextFrame() && 
static_cast<SwTextFrame*>(pRet)->IsHiddenNow() );
+    } while ( pRet && pRet->IsHiddenNow() );
     return pRet;
 }
 
@@ -1070,9 +1070,8 @@ void SwContentFrame::MakePrtArea( const SwBorderAttrs 
&rAttrs )
 
     setFramePrintAreaValid(true);
     SwRectFnSet aRectFnSet(this);
-    const bool bTextFrame = IsTextFrame();
     SwTwips nUpper = 0;
-    if ( bTextFrame && static_cast<SwTextFrame*>(this)->IsHiddenNow() )
+    if (IsTextFrame() && IsHiddenNow())
     {
         if ( static_cast<SwTextFrame*>(this)->HasFollow() )
             static_cast<SwTextFrame*>(this)->JoinFrame();
@@ -1702,7 +1701,7 @@ void SwContentFrame::MakeAll(vcl::RenderContext* 
/*pRenderContext*/)
                     const bool bMoveFwdInvalid = nullptr != GetIndNext();
                     const bool bNxtNew =
                         ( 0 == aRectFnSet.GetHeight(pNxt->getFramePrintArea()) 
) &&
-                        (!pNxt->IsTextFrame() 
||!static_cast<SwTextFrame*>(pNxt)->IsHiddenNow());
+                        !pNxt->IsHiddenNow();
 
                     pNxt->Calc(getRootFrame()->GetCurrShell()->GetOut());
 
@@ -2197,7 +2196,7 @@ bool SwContentFrame::WouldFit_( SwTwips nSpace,
                     pTmpPrev = nullptr;
                 else
                 {
-                    if( pFrame->IsTextFrame() && 
static_cast<SwTextFrame*>(pFrame)->IsHiddenNow() )
+                    if (pFrame->IsHiddenNow())
                         pTmpPrev = lcl_NotHiddenPrev( pFrame );
                     else
                         pTmpPrev = pFrame;
diff --git a/sw/source/core/layout/findfrm.cxx 
b/sw/source/core/layout/findfrm.cxx
index 37dc2807574d..8255ccf4a57f 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -953,7 +953,7 @@ SwFrame *SwFrame::FindNext_()
             (!bFootnote || pSct->IsInFootnote() ) )
             return pSct;
     }
-    return pRet;
+    return pRet == this ? nullptr : pRet;
 }
 
 // #i27138# - add parameter <_bInSameFootnote>
@@ -1339,11 +1339,7 @@ void SwFrame::InvalidateNextPrtArea()
     SwFrame* pNextFrame = FindNext();
     // skip empty section frames and hidden text frames
     {
-        while ( pNextFrame &&
-                ( ( pNextFrame->IsSctFrame() &&
-                    !static_cast<SwSectionFrame*>(pNextFrame)->GetSection() ) 
||
-                  ( pNextFrame->IsTextFrame() &&
-                    static_cast<SwTextFrame*>(pNextFrame)->IsHiddenNow() ) ) )
+        while (pNextFrame && pNextFrame->IsHiddenNow())
         {
             pNextFrame = pNextFrame->FindNext();
         }
diff --git a/sw/source/core/layout/flowfrm.cxx 
b/sw/source/core/layout/flowfrm.cxx
index 01f6b9e3cb34..77434724514c 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -1234,8 +1234,7 @@ bool SwFlowFrame::IsPageBreak( bool bAct ) const
 
         // Determine predecessor
         const SwFrame *pPrev = m_rThis.FindPrev();
-        while ( pPrev && ( !pPrev->IsInDocBody() ||
-                ( pPrev->IsTextFrame() && static_cast<const 
SwTextFrame*>(pPrev)->IsHiddenNow() ) ) )
+        while (pPrev && (!pPrev->IsInDocBody() || pPrev->IsHiddenNow()))
             pPrev = pPrev->FindPrev();
 
         if ( pPrev )
@@ -1296,7 +1295,7 @@ bool SwFlowFrame::IsColBreak( bool bAct ) const
             // Determine predecessor
             const SwFrame *pPrev = m_rThis.FindPrev();
             while( pPrev && ( ( !pPrev->IsInDocBody() && !m_rThis.IsInFly() && 
!m_rThis.FindFooterOrHeader() ) ||
-                   ( pPrev->IsTextFrame() && static_cast<const 
SwTextFrame*>(pPrev)->IsHiddenNow() ) ) )
+                   pPrev->IsHiddenNow() ) )
                     pPrev = pPrev->FindPrev();
 
             if ( pPrev )
@@ -1327,6 +1326,14 @@ bool SwFlowFrame::IsColBreak( bool bAct ) const
     return false;
 }
 
+// Skip hidden paragraphs and empty sections on the same level
+static const SwFrame* skipHiddenSiblingFrames_(const SwFrame* pFrame)
+{
+    while (pFrame && pFrame->IsHiddenNow())
+        pFrame = pFrame->GetPrev();
+    return pFrame;
+}
+
 bool SwFlowFrame::HasParaSpaceAtPages( bool bSct ) const
 {
     if( m_rThis.IsInSct() )
@@ -1342,7 +1349,7 @@ bool SwFlowFrame::HasParaSpaceAtPages( bool bSct ) const
                 return !pTmp->GetPrev() || IsPageBreak(true);
             if( pTmp->IsColumnFrame() && pTmp->GetPrev() )
                 return IsColBreak( true );
-            if( pTmp->IsSctFrame() && ( !bSct || pTmp->GetPrev() ) )
+            if (pTmp->IsSctFrame() && (!bSct || 
skipHiddenSiblingFrames_(pTmp->GetPrev())))
                 return false;
             pTmp = pTmp->GetUpper();
         }
@@ -1364,6 +1371,31 @@ bool SwFlowFrame::HasParaSpaceAtPages( bool bSct ) const
     return pTmp && !pTmp->GetPrev();
 }
 
+// Skip hidden paragraphs and empty sections
+static const SwFrame* skipHiddenFrames_(const SwFrame* pFrame)
+{
+    do
+    {
+        pFrame = skipHiddenSiblingFrames_(pFrame);
+        if (!pFrame || !pFrame->IsSctFrame())
+            return pFrame;
+        // Special case: found previous frame is a section
+        // Search for the last content in the section
+        auto pSectFrame = static_cast<const SwSectionFrame*>(pFrame);
+        pFrame = pSectFrame->FindLastContent();
+        // If the last content is in a table _inside_ the section,
+        // take the table herself.
+        // Correction: Check directly, if table is inside table, instead of 
indirectly
+        // by checking, if section isn't inside a table
+        if (pFrame && pFrame->IsInTab())
+        {
+            const SwTabFrame* pTableFrame = pFrame->FindTabFrame();
+            if (pSectFrame->IsAnLower(pTableFrame))
+                return pTableFrame;
+        }
+    } while (true);
+}
+
 /** helper method to determine previous frame for calculation of the
     upper space
 
@@ -1371,73 +1403,21 @@ bool SwFlowFrame::HasParaSpaceAtPages( bool bSct ) const
 */
 const SwFrame* SwFlowFrame::GetPrevFrameForUpperSpaceCalc_( const SwFrame* 
_pProposedPrevFrame ) const
 {
-    const SwFrame* pPrevFrame = _pProposedPrevFrame
-                            ? _pProposedPrevFrame
-                            : m_rThis.GetPrev();
-
-    // Skip hidden paragraphs and empty sections
-    while ( pPrevFrame &&
-            ( ( pPrevFrame->IsTextFrame() &&
-                static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) ||
-              ( pPrevFrame->IsSctFrame() &&
-                !static_cast<const SwSectionFrame*>(pPrevFrame)->GetSection() 
) ) )
-    {
-        pPrevFrame = pPrevFrame->GetPrev();
-    }
+    const SwFrame* pPrevFrame
+        = skipHiddenFrames_(_pProposedPrevFrame ? _pProposedPrevFrame : 
m_rThis.GetPrev());
+    if (pPrevFrame || !m_rThis.IsInFootnote()
+        || !(m_rThis.IsSctFrame() || !m_rThis.IsInSct() || 
!m_rThis.FindSctFrame()->IsInFootnote()))
+        return pPrevFrame;
 
     // Special case: no direct previous frame is found but frame is in footnote
     // Search for a previous frame in previous footnote,
     // if frame isn't in a section, which is also in the footnote
-    if ( !pPrevFrame && m_rThis.IsInFootnote() &&
-         ( m_rThis.IsSctFrame() ||
-           !m_rThis.IsInSct() || !m_rThis.FindSctFrame()->IsInFootnote() ) )
-    {
-        const SwFootnoteFrame* pPrevFootnoteFrame =
-                static_cast<const 
SwFootnoteFrame*>(m_rThis.FindFootnoteFrame()->GetPrev());
-        if ( pPrevFootnoteFrame )
-        {
-            pPrevFrame = pPrevFootnoteFrame->GetLastLower();
-
-            // Skip hidden paragraphs and empty sections
-            while ( pPrevFrame &&
-                    ( ( pPrevFrame->IsTextFrame() &&
-                        static_cast<const 
SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) ||
-                      ( pPrevFrame->IsSctFrame() &&
-                        !static_cast<const 
SwSectionFrame*>(pPrevFrame)->GetSection() ) ) )
-            {
-                pPrevFrame = pPrevFrame->GetPrev();
-            }
-        }
-    }
-    // Special case: found previous frame is a section
-    // Search for the last content in the section
-    if( pPrevFrame && pPrevFrame->IsSctFrame() )
-    {
-        const SwSectionFrame* pPrevSectFrame =
-                                    static_cast<const 
SwSectionFrame*>(pPrevFrame);
-        pPrevFrame = pPrevSectFrame->FindLastContent();
-        // If the last content is in a table _inside_ the section,
-        // take the table herself.
-        // Correction: Check directly, if table is inside table, instead of 
indirectly
-        // by checking, if section isn't inside a table
-        if ( pPrevFrame && pPrevFrame->IsInTab() )
-        {
-            const SwTabFrame* pTableFrame = pPrevFrame->FindTabFrame();
-            if ( pPrevSectFrame->IsAnLower( pTableFrame ) )
-            {
-                pPrevFrame = pTableFrame;
-            }
-        }
-        // Correction: skip hidden text frames
-        while ( pPrevFrame &&
-                pPrevFrame->IsTextFrame() &&
-                static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() )
-        {
-            pPrevFrame = pPrevFrame->GetPrev();
-        }
-    }
+    const SwFootnoteFrame* pPrevFootnoteFrame =
+            static_cast<const 
SwFootnoteFrame*>(m_rThis.FindFootnoteFrame()->GetPrev());
+    if ( pPrevFootnoteFrame )
+        return skipHiddenFrames_(pPrevFootnoteFrame->GetLastLower());
 
-    return pPrevFrame;
+    return nullptr;
 }
 
 /// Compare styles attached to these text frames.
@@ -1872,6 +1852,8 @@ SwTwips SwFlowFrame::CalcAddLowerSpaceAsLastInTableCell(
 /// Moves the Frame forward if it seems necessary regarding the current 
conditions and attributes.
 bool SwFlowFrame::CheckMoveFwd( bool& rbMakePage, bool bKeep, bool 
bIgnoreMyOwnKeepValue )
 {
+    if (m_rThis.IsHiddenNow())
+        return false;
     const SwFrame* pNxt = m_rThis.GetIndNext();
 
     if ( bKeep && //!bMovedBwd &&
@@ -2251,7 +2233,8 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat )
            )
             pNewUpper = m_rThis.GetLeaf( MAKEPAGE_FTN, false );
     }
-    else if ( IsPageBreak( true ) ) // Do we have to respect a PageBreak?
+    // Do we have to respect a PageBreak?
+    else if (IsPageBreak(true) && (!m_rThis.IsInSct() || 
!m_rThis.FindSctFrame()->IsHiddenNow()))
     {
         // If the previous page doesn't have a Frame in the body,
         // flowing back makes sense despite the PageBreak (otherwise,
@@ -2318,7 +2301,7 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat )
             }
         }
     }
-    else if ( IsColBreak( true ) )
+    else if (IsColBreak(true))
     {
         // If the previous column doesn't contain a ContentFrame, flowing back
         // makes sense despite the ColumnBreak, as otherwise we'd get
diff --git a/sw/source/core/layout/frmtool.cxx 
b/sw/source/core/layout/frmtool.cxx
index a1bb7d44bf71..6190e3e88017 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -832,11 +832,7 @@ void SwContentNotify::ImplDestroy()
         SwFrame* pPrevFrame = pCnt->FindPrev();
         // skip empty section frames and hidden text frames
         {
-            while ( pPrevFrame &&
-                    ( ( pPrevFrame->IsSctFrame() &&
-                        
!static_cast<SwSectionFrame*>(pPrevFrame)->GetSection() ) ||
-                      ( pPrevFrame->IsTextFrame() &&
-                        static_cast<SwTextFrame*>(pPrevFrame)->IsHiddenNow() ) 
) )
+            while (pPrevFrame && pPrevFrame->IsHiddenNow())
             {
                 pPrevFrame = pPrevFrame->FindPrev();
             }
@@ -1602,7 +1598,7 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
             pFrame = pNode->IsTextNode()
                         ? sw::MakeTextFrame(*pNode->GetTextNode(), pLay, eMode)
                         : pNode->MakeFrame(pLay);
-            if( pPageMaker )
+            if (pPageMaker && !pLay->IsHiddenNow())
                 pPageMaker->CheckInsert( nIndex );
 
             pFrame->InsertBehind( pLay, pPrv );
@@ -1762,15 +1758,11 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
                 continue; // skip it
             }
             SwSectionNode *pNode = static_cast<SwSectionNode*>(pNd);
-            if( pNode->GetSection().CalcHiddenFlag() )
-                // is hidden, skip the area
-                nIndex = pNode->EndOfSectionIndex();
-            else
             {
                 if (pActualSection)
                     pActualSection->SetLastPos(pPrv);
 
-                pFrame = pNode->MakeFrame( pLay );
+                pFrame = pNode->MakeFrame(pLay, 
pNode->GetSection().CalcHiddenFlag());
                 pActualSection.reset( new SwActualSection( 
pActualSection.release(),
                                                 
static_cast<SwSectionFrame*>(pFrame), pNode ) );
                 if ( pActualSection->GetUpper() )
@@ -1941,7 +1933,8 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
                 }
                 else
                 {
-                    pFrame = pActualSection->GetSectionNode()->MakeFrame( pLay 
);
+                    pFrame = pActualSection->GetSectionNode()->MakeFrame(
+                        pLay, 
pActualSection->GetSectionNode()->GetSection().IsHiddenFlag());
                     pFrame->InsertBehind( pLay, pPrv );
                     static_cast<SwSectionFrame*>(pFrame)->Init();
 
@@ -2534,8 +2527,7 @@ void SwBorderAttrs::CalcJoinedWithPrev( const SwFrame& 
_rFrame,
         // one as previous frame.
         const SwFrame* pPrevFrame = _pPrevFrame ? _pPrevFrame : 
_rFrame.GetPrev();
         // OD 2004-02-13 #i25029# - skip hidden text frames.
-        while ( pPrevFrame && pPrevFrame->IsTextFrame() &&
-                static_cast<const SwTextFrame*>(pPrevFrame)->IsHiddenNow() )
+        while (pPrevFrame && pPrevFrame->IsHiddenNow())
         {
             pPrevFrame = pPrevFrame->GetPrev();
         }
@@ -2566,8 +2558,7 @@ void SwBorderAttrs::CalcJoinedWithNext( const SwFrame& 
_rFrame )
         // corresponding attribute set is set at current text frame.
         // OD 2004-02-13 #i25029# - get next frame, but skip hidden text 
frames.
         const SwFrame* pNextFrame = _rFrame.GetNext();
-        while ( pNextFrame && pNextFrame->IsTextFrame() &&
-                static_cast<const SwTextFrame*>(pNextFrame)->IsHiddenNow() )
+        while (pNextFrame && pNextFrame->IsHiddenNow())
         {
             pNextFrame = pNextFrame->GetNext();
         }
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index 6fb88185a6f2..71d694d885f7 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -2955,13 +2955,9 @@ SwContentFrame* SwFootnoteFrame::FindLastContent()
     while ( pTmpLastLower && pTmpLastLower->GetNext() )
     {
         pTmpLastLower = pTmpLastLower->GetNext();
-        if ( ( pTmpLastLower->IsTextFrame() &&
-               !static_cast<SwTextFrame*>(pTmpLastLower)->IsHiddenNow() ) ||
-             ( pTmpLastLower->IsSctFrame() &&
-               static_cast<SwSectionFrame*>(pTmpLastLower)->GetSection() &&
-               static_cast<SwSectionFrame*>(pTmpLastLower)->ContainsContent() 
) ||
-             ( pTmpLastLower->IsTabFrame() &&
-               static_cast<SwTabFrame*>(pTmpLastLower)->ContainsContent() ) )
+        if (!pTmpLastLower->IsHiddenNow()
+            && (!pTmpLastLower->IsLayoutFrame()
+                || 
static_cast<SwLayoutFrame*>(pTmpLastLower)->ContainsContent()))
         {
             pLastLowerOfFootnote = pTmpLastLower;
         }
diff --git a/sw/source/core/layout/pagechg.cxx 
b/sw/source/core/layout/pagechg.cxx
index da4c2fb81c5d..837cf1a0a502 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -785,7 +785,10 @@ SwPageDesc *SwPageFrame::FindPageDesc()
         return pRet;
     }
 
-    SwFrame *pFlow = FindFirstBodyContent();
+    SwContentFrame* pFirstContent = FindFirstBodyContent();
+    while (pFirstContent && pFirstContent->IsHiddenNow())
+        pFirstContent = pFirstContent->GetNextContentFrame();
+    SwFrame* pFlow = pFirstContent;
     if ( pFlow && pFlow->IsInTab() )
         pFlow = pFlow->FindTabFrame();
 
diff --git a/sw/source/core/layout/sectfrm.cxx 
b/sw/source/core/layout/sectfrm.cxx
index b86ccbf1b31d..592fe32e7704 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -189,6 +189,13 @@ SwSectionFrame::~SwSectionFrame()
 {
 }
 
+//virtual
+bool SwSectionFrame::IsHiddenNow() const
+{
+    const auto* pSection = GetSection();
+    return !pSection || pSection->CalcHiddenFlag();
+}
+
 void SwSectionFrame::DelEmpty( bool bRemove )
 {
     if( IsColLocked() )
@@ -1371,6 +1378,20 @@ void SwSectionFrame::Format( vcl::RenderContext* 
pRenderContext, const SwBorderA
 
     SwRectFnSet aRectFnSet(this);
 
+    if (GetSection()->CalcHiddenFlag())
+    {
+        {
+            SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
+            aRectFnSet.SetHeight(aFrm, 0);
+        }
+        {
+            SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
+            aRectFnSet.SetHeight(aPrt, 0);
+        }
+        setFrameAreaSizeValid(true);
+        setFramePrintAreaValid(true);
+    }
+
     if ( !isFramePrintAreaValid() )
     {
         PROTOCOL( this, PROT::PrintArea, DbgAction::NONE, nullptr )
@@ -2182,6 +2203,11 @@ bool SwSectionFrame::Growable() const
 
 SwTwips SwSectionFrame::Grow_( SwTwips nDist, bool bTst )
 {
+    if (GetSection()->CalcHiddenFlag())
+    {
+        return 0;
+    }
+
     if ( !IsColLocked() && !HasFixSize() )
     {
         SwRectFnSet aRectFnSet(this);
@@ -2646,6 +2672,17 @@ void SwSectionFrame::SwClientNotify(const SwModify& 
rMod, const SfxHint& rHint)
             return;
         SwSectionFrame::MoveContentAndDelete(this, pHint->IsSaveContent());
     }
+    else if (rHint.GetId() == SfxHintId::SwSectionHidden)
+    {
+        InvalidateAll();
+        InvalidateObjs(false);
+
+        for (SwFrame* pLowerFrame = Lower(); pLowerFrame; pLowerFrame = 
pLowerFrame->GetNext())
+        {
+            pLowerFrame->InvalidateAll();
+            pLowerFrame->InvalidateObjs(false);
+        }
+    }
     else
         SwFrame::SwClientNotify(rMod, rHint);
 }
diff --git a/sw/source/core/layout/trvlfrm.cxx 
b/sw/source/core/layout/trvlfrm.cxx
index dfcfad57cef5..709071face41 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -49,6 +49,7 @@
 #include <frmtool.hxx>
 #include <ndtxt.hxx>
 #include <undobj.hxx>
+#include <sectfrm.hxx>
 
 #include <swselectionlist.hxx>
 #include <comphelper/lok.hxx>
@@ -803,8 +804,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame 
*pStart,
         //If I'm in the DocumentBody, I want to stay there.
         if ( pStart->IsInDocBody() )
         {
-            while ( pCnt && (!pCnt->IsInDocBody() ||
-                             (pCnt->IsTextFrame() && static_cast<const 
SwTextFrame*>(pCnt)->IsHiddenNow())))
+            while (pCnt && (!pCnt->IsInDocBody() || pCnt->IsHiddenNow()))
             {
                 pCnt = (*fnNxtPrv)( pCnt );
                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, 
bInReadOnly, bTableSel );
@@ -815,8 +815,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame 
*pStart,
         //case of necessity.
         else if ( pStart->IsInFootnote() )
         {
-            while ( pCnt && (!pCnt->IsInFootnote() ||
-                            (pCnt->IsTextFrame() && static_cast<const 
SwTextFrame*>(pCnt)->IsHiddenNow())))
+            while (pCnt && (!pCnt->IsInFootnote() || pCnt->IsHiddenNow()))
             {
                 pCnt = (*fnNxtPrv)( pCnt );
                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, 
bInReadOnly, bTableSel );
@@ -826,7 +825,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame 
*pStart,
         //In Flys we can go ahead blindly as long as we find a Content.
         else if ( pStart->IsInFly() )
         {
-            if ( pCnt && pCnt->IsTextFrame() && static_cast<const 
SwTextFrame*>(pCnt)->IsHiddenNow() )
+            if (pCnt && pCnt->IsHiddenNow())
             {
                 pCnt = (*fnNxtPrv)( pCnt );
                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, 
bInReadOnly, bTableSel );
@@ -850,7 +849,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame 
*pStart,
             }
             if ( !bSame )
                 pCnt = nullptr;
-            else if (pCnt->IsTextFrame() && static_cast<const 
SwTextFrame*>(pCnt)->IsHiddenNow()) // i73332
+            else if (pCnt->IsHiddenNow()) // i73332
             {
                 pCnt = (*fnNxtPrv)( pCnt );
                 pCnt = ::lcl_MissProtectedFrames( pCnt, fnNxtPrv, true, 
bInReadOnly, bTableSel );
@@ -933,8 +932,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame 
*pStart,
             }
         }
 
-    } while ( !bEnd ||
-              (pCnt && pCnt->IsTextFrame() && static_cast<const 
SwTextFrame*>(pCnt)->IsHiddenNow()));
+    } while (!bEnd || (pCnt && pCnt->IsHiddenNow()));
 
     if (pCnt == nullptr)
     {
@@ -1221,7 +1219,7 @@ const SwContentFrame *SwLayoutFrame::GetContentPos( 
Point& rPoint,
                 if ( pComp != pContent )
                     continue;
 
-                if ( !pContent->IsTextFrame() || !static_cast<const 
SwTextFrame*>(pContent)->IsHiddenNow() )
+                if (!pContent->IsHiddenNow())
                 {
                     SwRect aContentFrame( pContent->UnionFrame() );
                     if ( aContentFrame.Contains( rPoint ) )
@@ -1702,6 +1700,15 @@ bool SwFrame::IsProtected() const
     return false;
 }
 
+// virtual
+bool SwFrame::IsHiddenNow() const
+{
+    if (const auto* pSectFrame = FindSctFrame())
+        return pSectFrame->IsHiddenNow();
+
+    return false;
+}
+
 /** @return the physical page number */
 sal_uInt16 SwFrame::GetPhyPageNum() const
 {
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 90b0a9e743e3..59df520e50d0 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -1367,6 +1367,9 @@ bool SwTextFrame::IsHiddenNow() const
         return true;
     }
 
+    if (SwContentFrame::IsHiddenNow())
+        return true;
+
     bool bHiddenCharsHidePara(false);
     bool bHiddenParaField(false);
     if (m_pMergedPara)
@@ -1436,22 +1439,14 @@ bool SwTextFrame::IsHiddenNow() const
             // be visible - check this for the 1st body paragraph
             if (IsInDocBody() && FindPrevCnt() == nullptr)
             {
-                bool isAllHidden(true);
                 for (SwContentFrame const* pNext = FindNextCnt(true);
                         pNext != nullptr; pNext = pNext->FindNextCnt(true))
                 {
-                    if (!pNext->IsTextFrame()
-                        || !static_cast<SwTextFrame 
const*>(pNext)->IsHiddenNow())
-                    {
-                        isAllHidden = false;
-                        break;
-                    }
-                }
-                if (isAllHidden)
-                {
-                    SAL_INFO("sw.core", "unhiding one body paragraph");
-                    return false;
+                    if (!pNext->IsHiddenNow())
+                        return true;
                 }
+                SAL_INFO("sw.core", "unhiding one body paragraph");
+                return false;
             }
             return true;
         }

Reply via email to