diff options
-rw-r--r-- | sw/qa/core/layout/data/inline-endnote-and-footnote.doc | bin | 0 -> 24576 bytes | |||
-rw-r--r-- | sw/qa/core/layout/ftnfrm.cxx | 21 | ||||
-rw-r--r-- | sw/source/core/layout/flowfrm.cxx | 37 | ||||
-rw-r--r-- | sw/source/core/layout/ftnfrm.cxx | 45 | ||||
-rw-r--r-- | sw/source/core/text/txtftn.cxx | 10 |
5 files changed, 83 insertions, 30 deletions
diff --git a/sw/qa/core/layout/data/inline-endnote-and-footnote.doc b/sw/qa/core/layout/data/inline-endnote-and-footnote.doc Binary files differnew file mode 100644 index 000000000000..39c5636e1e12 --- /dev/null +++ b/sw/qa/core/layout/data/inline-endnote-and-footnote.doc diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx index 4c874202da3f..71fd3fd67150 100644 --- a/sw/qa/core/layout/ftnfrm.cxx +++ b/sw/qa/core/layout/ftnfrm.cxx @@ -63,4 +63,25 @@ CPPUNIT_TEST_FIXTURE(Test, testFlySplitFootnoteLayout) CPPUNIT_ASSERT(pPage->FindFootnoteCont()); } +CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndFootnote) +{ + // Given a DOC file with an endnote and then a footnote: + createSwDoc("inline-endnote-and-footnote.doc"); + + // When laying out that document: + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + + // Then make sure the footnote is below the endnote: + // Without the accompanying fix in place, this test would have failed with: + // - xpath should match exactly 1 node + // i.e. the endnote was also in the footnote container, not at the end of the body text. + sal_Int32 nEndnoteTop + = parseDump("/root/page/body/section/column/ftncont/ftn/infos/bounds"_ostr, "top"_ostr) + .toInt32(); + sal_Int32 nFootnoteTop + = parseDump("/root/page/ftncont/ftn/infos/bounds"_ostr, "top"_ostr).toInt32(); + // Endnote at the end of body text, footnote at page bottom. + CPPUNIT_ASSERT_LESS(nFootnoteTop, nEndnoteTop); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index 37fd20b323d7..1cb5cf7bf47a 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -2257,18 +2257,47 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat ) const bool bEndnote = pFootnote->GetAttr()->GetFootnote().IsEndNote(); const IDocumentSettingAccess& rSettings = pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess(); - if( bEndnote && pFootnote->IsInSct() ) + bool bContEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES); + if( bEndnote && pFootnote->IsInSct() && !bContEndnotes) { SwSectionFrame* pSect = pFootnote->FindSctFrame(); if( pSect->IsEndnAtEnd() ) // Endnotes at the end of the section. pRef = pSect->FindLastContent( SwFindMode::LastCnt ); } - else if (bEndnote && rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES)) + else if (bEndnote && bContEndnotes) { // Endnotes at the end of the document. - SwPageFrame* pPage = m_rThis.getRootFrame()->GetLastPage(); - pRef = pPage->FindLastBodyContent(); + SwSectionFrame* pSect = pFootnote->FindSctFrame(); + if (!pSect->GetPrev() && !pSect->FindMaster()) + { + // The section is at the top of the page, and is not a follow of a master section. + // See if there is a previous body frame. + SwLayoutFrame* pPrev = pSect->GetPrevLayoutLeaf(); + if (pPrev && pPrev->IsBodyFrame()) + { + // There is, then see if that's on a different page. + SwPageFrame* pSectPage = pSect->FindPageFrame(); + SwPageFrame* pPage = pPrev->FindPageFrame(); + if (pPage != pSectPage) + { + // It is, then create a new section frame at the end of that previous body + // frame. + auto pNew = new SwSectionFrame(*pSect, /*bMaster=*/true); + pNew->InsertBehind(pPage->FindBodyCont(), pPage->FindLastBodyContent()); + pNew->Init(); + SwFrame* pLower = pNew->GetLower(); + if (pLower->IsColumnFrame()) + { + pRef = pLower; + } + } + } + } + else + { + pRef = pFootnote->FindFootnoteBossFrame(); + } } if( !pRef ) // Endnotes on a separate page. diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx index 0fd430ccc31d..e03519ed3040 100644 --- a/sw/source/core/layout/ftnfrm.cxx +++ b/sw/source/core/layout/ftnfrm.cxx @@ -768,26 +768,18 @@ SwLayoutFrame *SwFrame::GetPrevFootnoteLeaf( MakePageType eMakeFootnote ) SwFrame* pTmpRef = nullptr; const IDocumentSettingAccess& rSettings = pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess(); - if( bEndn && pFootnote->IsInSct() ) + bool bContEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES); + if( bEndn && pFootnote->IsInSct() && !bContEndnotes) { SwSectionFrame* pSect = pFootnote->FindSctFrame(); if( pSect->IsEndnAtEnd() ) // Endnotes at the end of the section. pTmpRef = pSect->FindLastContent( SwFindMode::LastCnt ); } - else if (bEndn && rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES)) + else if (bEndn && bContEndnotes) { // Endnotes at the end of the document. - SwPageFrame* pPage = getRootFrame()->GetLastPage(); - assert(pPage); - SwFrame* pPrevPage = pPage->GetPrev(); - if (pPrevPage) - { - // Have a last but one page, use that since we try to get a preceding frame. - assert(pPrevPage->IsPageFrame()); - pPage = static_cast<SwPageFrame*>(pPrevPage); - } - pTmpRef = pPage->FindLastBodyContent(); + pTmpRef = pFootnote->FindFootnoteBossFrame(); } if( !pTmpRef ) // Endnotes on a separate page. @@ -1581,8 +1573,28 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame *pRef, SwTextFootnote * else if (rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES)) { // Endnotes at the end of the document. - pBoss = getRootFrame()->GetLastPage(); - pPage = pBoss->FindPageFrame(); + // Find the first page that hosts an endnote section. + SwSectionFrame* pEndnoteSection = pPage->GetEndNoteSection(); + while (pPage->GetNext() && !pEndnoteSection) + { + pPage = pPage->GetNext()->DynCastPageFrame(); + pEndnoteSection = pPage->GetEndNoteSection(); + } + // If there are no endnotes sections yet, create one at the end of the document. + if (!pEndnoteSection) + { + SwSection* pSwSection = pDoc->GetEndNoteInfo().GetSwSection(*pDoc); + pEndnoteSection = new SwSectionFrame(*pSwSection, pPage); + pEndnoteSection->InsertBehind(pPage->FindBodyCont(), pPage->FindLastBodyContent()); + pEndnoteSection->Init(); + pEndnoteSection->SetEndNoteSection(true); + } + + SwFrame* pColumnFrame = pEndnoteSection->GetLower(); + if (pColumnFrame->IsColumnFrame()) + { + pBoss = static_cast<SwColumnFrame*>(pColumnFrame); + } } else { @@ -1931,10 +1943,7 @@ void SwFootnoteBossFrame::CollectFootnotes_( const SwContentFrame* _pRef, bool bCollectFoundFootnote = false; // Ignore endnotes which are on a separate endnote page. bool bEndNote = _pFootnote->GetAttr()->GetFootnote().IsEndNote(); - const IDocumentSettingAccess& rSettings - = _pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess(); - bool bContinuousEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES); - if (_pFootnote->GetRef() == _pRef && (!bEndNote || bContinuousEndnotes)) + if (_pFootnote->GetRef() == _pRef && !bEndNote) { if (_pRefFootnoteBossFrame) { diff --git a/sw/source/core/text/txtftn.cxx b/sw/source/core/text/txtftn.cxx index 35bb31f76a4c..bb21b6ab0f29 100644 --- a/sw/source/core/text/txtftn.cxx +++ b/sw/source/core/text/txtftn.cxx @@ -598,8 +598,6 @@ void SwTextFrame::ConnectFootnote( SwTextFootnote *pFootnote, const SwTwips nDea mbFootnote = true; mbInFootnoteConnect = true; // Just reset! // See if pFootnote is an endnote on a separate endnote page. - const IDocumentSettingAccess& rSettings = GetDoc().getIDocumentSettingAccess(); - const bool bContinuousEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES); const bool bEnd = pFootnote->GetFootnote().IsEndNote(); // We want to store this value, because it is needed as a fallback @@ -630,15 +628,11 @@ void SwTextFrame::ConnectFootnote( SwTextFootnote *pFootnote, const SwTwips nDea if( bDocEnd ) { - if ((pSect || bContinuousEndnotes) && pSrcFrame) + if (pSect && pSrcFrame) { SwFootnoteFrame *pFootnoteFrame = SwFootnoteBossFrame::FindFootnote( pSrcFrame, pFootnote ); - if (pFootnoteFrame && (pFootnoteFrame->IsInSct() || bContinuousEndnotes)) + if (pFootnoteFrame && pFootnoteFrame->IsInSct()) { - // We either have a foot/endnote that goes to the end of the section or are in Word - // compatibility mode where endnotes go to the end of the document. Handle both - // cases by removing the footnote here, then later appending them to the correct - // last page of the document or section. pBoss->RemoveFootnote( pSrcFrame, pFootnote ); pSrcFrame = nullptr; } |