diff options
27 files changed, 362 insertions, 163 deletions
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx index 20636648c794..bddea2b87cb6 100644 --- a/sw/inc/crsrsh.hxx +++ b/sw/inc/crsrsh.hxx @@ -267,7 +267,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 de7e24a0b152..b1e3309d596f 100644 --- a/sw/inc/node.hxx +++ b/sw/inc/node.hxx @@ -590,7 +590,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/layout3.cxx b/sw/qa/extras/layout/layout3.cxx index 9c46d8395a1e..a074a35dc61b 100644 --- a/sw/qa/extras/layout/layout3.cxx +++ b/sw/qa/extras/layout/layout3.cxx @@ -94,15 +94,25 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf119875) { createSwDoc("tdf119875.odt"); xmlDocUniquePtr pXmlDoc = parseLayoutDump(); - sal_Int32 nFirstTop - = getXPath(pXmlDoc, "/root/page[2]/body/section[1]/infos/bounds"_ostr, "top"_ostr) - .toInt32(); - sal_Int32 nSecondTop - = getXPath(pXmlDoc, "/root/page[2]/body/section[2]/infos/bounds"_ostr, "top"_ostr) - .toInt32(); - // The first section had the same top value as the second one, so they - // overlapped. - CPPUNIT_ASSERT_LESS(nSecondTop, nFirstTop); + + assertXPath(pXmlDoc, "//page[2]/body/section[1]"_ostr, "formatName"_ostr, u"S10"_ustr); + assertXPath(pXmlDoc, "//page[2]/body/section[2]"_ostr, "formatName"_ostr, u"S11"_ustr); + assertXPath(pXmlDoc, "//page[2]/body/section[3]"_ostr, "formatName"_ostr, u"S13"_ustr); + assertXPath(pXmlDoc, "//page[2]/body/section[4]"_ostr, "formatName"_ostr, u"S14"_ustr); + // Sections "S10" and "S13" are hidden -> their frames are zero-height + assertXPath(pXmlDoc, "//page[2]/body/section[1]/infos/bounds"_ostr, "height"_ostr, u"0"_ustr); + assertXPath(pXmlDoc, "//page[2]/body/section[3]/infos/bounds"_ostr, "height"_ostr, u"0"_ustr); + + OUString S10Top = getXPath(pXmlDoc, "//page[2]/body/section[1]/infos/bounds"_ostr, "top"_ostr); + OUString S11Top = getXPath(pXmlDoc, "//page[2]/body/section[2]/infos/bounds"_ostr, "top"_ostr); + OUString S13Top = getXPath(pXmlDoc, "//page[2]/body/section[3]/infos/bounds"_ostr, "top"_ostr); + OUString S14Top = getXPath(pXmlDoc, "//page[2]/body/section[4]/infos/bounds"_ostr, "top"_ostr); + + 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(SwLayoutWriter3, testTdf137523) @@ -2303,6 +2313,46 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf159259) CPPUNIT_ASSERT_EQUAL(paraHeight, flyHeight); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, 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"_ostr, 1); + assertXPath(pXmlDoc, "//page/body/section"_ostr, 2); + assertXPath(pXmlDoc, "//page/body/section[1]/infos/bounds"_ostr, "height"_ostr, u"0"_ustr); + // 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"_ostr, "height"_ostr, u"1680"_ustr); +} + +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testPageBreakInHiddenSection) +{ + // Given a paragraph with page-break-before with page style and page number + createSwDoc("pageBreakInHiddenSection.fodt"); + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "//page"_ostr, 4); + assertXPath(pXmlDoc, "//section"_ostr, 4); + assertXPath(pXmlDoc, "//page[1]/body/txt"_ostr, 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"_ostr, 2); + // The first section is hidden + assertXPath(pXmlDoc, "//page[1]/body/section[1]/infos/bounds"_ostr, "height"_ostr, u"0"_ustr); + + // Page 2 is empty even page (generated by the next page's section with page-break-before) + assertXPath(pXmlDoc, "//page[2]/body"_ostr, 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"_ostr, 1); + assertXPath(pXmlDoc, "//page[3]/body/section/infos/bounds"_ostr, "height"_ostr, u"0"_ustr); + + // 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"_ostr, 1); + assertXPath(pXmlDoc, "//page[4]/body/section/infos/bounds"_ostr, "height"_ostr, u"0"_ustr); +} + 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/uiwriter9.cxx b/sw/qa/extras/uiwriter/uiwriter9.cxx index 1a3e49c25754..f870f5ea480a 100644 --- a/sw/qa/extras/uiwriter/uiwriter9.cxx +++ b/sw/qa/extras/uiwriter/uiwriter9.cxx @@ -122,6 +122,22 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf135083) CPPUNIT_ASSERT(!getProperty<OUString>(xLastPara, u"ListId"_ustr).isEmpty()); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testHiddenSectionsAroundPageBreak) +{ + createSwDoc("hiddenSectionsAroundPageBreak.fodt"); + + CPPUNIT_ASSERT_EQUAL(1, getPages()); + + auto xModel(mxComponent.queryThrow<frame::XModel>()); + auto xTextViewCursorSupplier( + xModel->getCurrentController().queryThrow<text::XTextViewCursorSupplier>()); + auto xCursor(xTextViewCursorSupplier->getViewCursor().queryThrow<text::XPageCursor>()); + + // Make sure that the page style is set correctly + xCursor->jumpToFirstPage(); + CPPUNIT_ASSERT_EQUAL(u"Landscape"_ustr, getProperty<OUString>(xCursor, "PageStyleName")); +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx index 173414ed4db7..d08e4971f556 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -944,14 +944,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 @@ -992,7 +992,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)) @@ -1796,7 +1796,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(); @@ -1805,14 +1805,14 @@ void SwCursorShell::UpdateCursorPos() pShellCursor->DeleteMark(); // kde45196-1.html: try to get to a non-hidden paragraph, there must // be one in the document body - while (isInHiddenTextFrame(pShellCursor)) + while (isInHiddenFrame(pShellCursor)) { if (!pShellCursor->MovePara(GoNextPara, fnParaStart)) { break; } } - while (isInHiddenTextFrame(pShellCursor)) + while (isInHiddenFrame(pShellCursor)) { if (!pShellCursor->MovePara(GoPrevPara, fnParaStart)) { diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx index 25bf8d0ef68e..4f2ceb0a841d 100644 --- a/sw/source/core/crsr/pam.cxx +++ b/sw/source/core/crsr/pam.cxx @@ -1060,7 +1060,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() @@ -1101,8 +1101,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 c78d8e18b633..2a5aad64de21 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 cf96e1d5094b..1da9ecb43ed6 100644 --- a/sw/source/core/docnode/ndsect.cxx +++ b/sw/source/core/docnode/ndsect.cxx @@ -1022,9 +1022,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 c6ecb9ccf974..8967833a64b1 100644 --- a/sw/source/core/docnode/nodes.cxx +++ b/sw/source/core/docnode/nodes.cxx @@ -1963,7 +1963,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(); @@ -1974,7 +1974,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(); @@ -1985,7 +1985,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 12d9e281c2f0..53418541eb4c 100644 --- a/sw/source/core/docnode/section.cxx +++ b/sw/source/core/docnode/section.cxx @@ -299,14 +299,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() ) @@ -314,8 +311,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 333eecd35262..0400dc887169 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 d57654f6a9e7..604488a18c9f 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -891,6 +891,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 c07d78b12ba9..69158b335863 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 e60dbd20fb97..df11ca589bc6 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -559,7 +559,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 c2bbdd8904f8..e13fdf012143 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -177,7 +177,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 @@ -209,7 +209,7 @@ bool SwContentFrame::ShouldBwdMoved( SwLayoutFrame *pNewUpper, bool & ) } // Check for space left in new upper - return nSpace != 0; + return nSpace != 0 || IsHiddenNow(); } } return false; @@ -532,7 +532,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; } @@ -1083,9 +1083,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(); @@ -1715,7 +1714,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()); @@ -2217,7 +2216,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 5331baacd93e..0dd64c6aecff 100644 --- a/sw/source/core/layout/findfrm.cxx +++ b/sw/source/core/layout/findfrm.cxx @@ -994,7 +994,7 @@ SwFrame *SwFrame::FindNext_() (!bFootnote || pSct->IsInFootnote() ) ) return pSct; } - return pRet; + return pRet == this ? nullptr : pRet; } // #i27138# - add parameter <_bInSameFootnote> @@ -1380,11 +1380,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 da509e2a6bea..88158161c530 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -1271,8 +1271,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 ) @@ -1333,7 +1332,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 ) @@ -1364,6 +1363,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() ) @@ -1379,7 +1386,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(); } @@ -1401,6 +1408,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 @@ -1408,73 +1440,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; } // This should be renamed to something like lcl_UseULSpacing @@ -1912,6 +1892,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 && @@ -2299,7 +2281,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, @@ -2366,7 +2349,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 eeab5c60c1ce..baf632d6ebff 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -844,11 +844,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(); } @@ -1608,7 +1604,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 ); @@ -1766,15 +1762,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() ) @@ -1945,7 +1937,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(); @@ -2523,8 +2516,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(); } @@ -2555,8 +2547,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 70453c572774..f4e6072498d1 100644 --- a/sw/source/core/layout/ftnfrm.cxx +++ b/sw/source/core/layout/ftnfrm.cxx @@ -2965,13 +2965,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 bf4bcc45ea3a..f8c029ea12cd 100644 --- a/sw/source/core/layout/pagechg.cxx +++ b/sw/source/core/layout/pagechg.cxx @@ -789,7 +789,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 a1fd849ec495..3967a1f56442 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/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index f75782456181..a04f9a14a7b3 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -1454,6 +1454,8 @@ namespace auto IsAllHiddenSection(SwSectionFrame const& rSection) -> bool { + if (rSection.IsHiddenNow()) + return true; for (SwFrame const* pFrame = rSection.Lower(); pFrame; pFrame = pFrame->GetNext()) { if (pFrame->IsColumnFrame()) @@ -1474,7 +1476,7 @@ namespace } else if (pFrame->IsTextFrame()) { - if (!static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()) + if (!pFrame->IsHiddenNow()) { return false; } @@ -1509,7 +1511,7 @@ namespace } else if (pFrame->IsTextFrame()) { - if (!static_cast<SwTextFrame const*>(pFrame)->IsHiddenNow()) + if (!pFrame->IsHiddenNow()) { return false; } diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index a8445e90dd5a..89a5f03302ac 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -52,6 +52,7 @@ #include <ndtxt.hxx> #include <undobj.hxx> #include <flyfrms.hxx> +#include <sectfrm.hxx> #include <swselectionlist.hxx> #include <comphelper/lok.hxx> @@ -828,8 +829,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 ); @@ -840,8 +840,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 ); @@ -851,7 +850,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 ); @@ -875,7 +874,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 ); @@ -958,8 +957,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) { @@ -1246,7 +1244,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 ) ) @@ -1727,6 +1725,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 302302a9a256..52a51ff1a509 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -1485,6 +1485,9 @@ bool SwTextFrame::IsHiddenNow() const return true; } + if (SwContentFrame::IsHiddenNow()) + return true; + bool bHiddenCharsHidePara(false); bool bHiddenParaField(false); if (m_pMergedPara) @@ -1554,22 +1557,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; } |