sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf |binary sw/qa/extras/layout/layout.cxx | 9 +++ sw/source/core/layout/objectformattertxtfrm.cxx | 52 ++++++++++++++++------ 3 files changed, 47 insertions(+), 14 deletions(-)
New commits: commit b845927ed4e3987a578b0c8ded46ddbc7833e7ff Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Wed Feb 23 16:45:31 2022 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Mar 2 13:31:12 2022 +0100 sw: really prevent footnote frame against delete while it's moved This reverts commit fe5d3fbfe63fe8b433776bd3a0508dd712b868b0 (on master only) It turns out that checking a single column's IsMovingFootnotes() is not enough - as frames can move both forwards and backwards the entire chain of columns would need to be checked. (Most callers of MoveLowerFootnotes() move forwards, but one place in tabfrm.cxx moves from a follow to master.) But it turns out that this is probably the wrong way in any case: most likely the intention in FormatAnchorFrameAndItsPrevs() is to format previous frames in the same layout environment, so if there is a section or column inside a footnote then this upper should be formatted, while if the footnote is inside a section or column this upper should not be formatted; this should make calls during MoveFootnotes_() safe as it should prevent the formatting of frames in the footnote boss moving a footnote that is already being moved. So tweak the fix in commit fa1bcc22921941b2cd8a0b32fe0d15655d12d607 a little to make it more general. Also it was previously possible that for a section with columns, both the section branch and the column branch was taken, which seems supperfluous. Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130544 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 3f569ffc9238e6bf2915e78bf21c844ca5f1270d) add a layout test to exercise UXTSOREL Change-Id: I57b29dd7d73c08bdbf227676c4ce9034aabf418a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130493 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit 10d46c0498b89350645cf45e744a528d3d8f1ac1) Change-Id: I39487640322339fe4d511e845d9c6bced2ba9dad Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130831 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf b/sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf new file mode 100644 index 000000000000..1020269ae119 Binary files /dev/null and b/sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf differ diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 0c7a4dc13ff0..94edf650a359 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -2478,6 +2478,15 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepoint75) createSwDoc(DATA_DIRECTORY, "forcepoint75-1.rtf"); } +// FIXME: apparently infinite loop on Mac +#ifndef MACOSX +//just care it doesn't crash/assert +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testUXTSOREL) +{ + createSwDoc(DATA_DIRECTORY, "LIBREOFFICE-UXTSOREL.rtf"); +} +#endif + //just care it doesn't crash/assert CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testForcepointFootnoteFrame) { diff --git a/sw/source/core/layout/objectformattertxtfrm.cxx b/sw/source/core/layout/objectformattertxtfrm.cxx index 26d503511064..d0fa8cf1be84 100644 --- a/sw/source/core/layout/objectformattertxtfrm.cxx +++ b/sw/source/core/layout/objectformattertxtfrm.cxx @@ -829,21 +829,46 @@ void SwObjectFormatterTextFrame::FormatAnchorFrameAndItsPrevs( SwTextFrame& _rAn // for follow text frames. if ( !_rAnchorTextFrame.IsFollow() ) { + // In case the anchor frame is in a column or section, format its + // previous frames first - but don't jump out of the current layout + // environment, e.g. from footnotes into the footnote boss. + SwFrame * pSectFrame(nullptr); + SwFrame * pColFrameOfAnchor(nullptr); + for (SwFrame* pUpper = _rAnchorTextFrame.GetUpper(); + pUpper != nullptr; pUpper = pUpper->GetUpper()) + { + if (pUpper->IsCellFrame()) + { + break; // apparently nothing to be done? + } + if (pUpper->IsFootnoteFrame()) + { + SAL_INFO_IF(pColFrameOfAnchor == nullptr && pUpper->FindColFrame(), + "sw.layout", "tdf#122894 skipping column for footnote in column"); + break; // stop: prevent crash in case footnotes are being moved + } + if (pUpper->IsSctFrame()) + { + pColFrameOfAnchor = nullptr; + pSectFrame = pUpper; + break; + } + if (pColFrameOfAnchor != nullptr) + { // parent of column not a section frame => column not in section + break; + } + if (pUpper->IsColumnFrame()) + { + pColFrameOfAnchor = pUpper; + } + } + // if anchor frame is directly inside a section, format this section and // its previous frames. // Note: It's a very simple format without formatting objects. - if ( _rAnchorTextFrame.IsInSct() ) + if (pSectFrame) { - SwFrame* pSectFrame = _rAnchorTextFrame.GetUpper(); - while ( pSectFrame ) - { - if ( pSectFrame->IsSctFrame() || pSectFrame->IsCellFrame() ) - { - break; - } - pSectFrame = pSectFrame->GetUpper(); - } - if ( pSectFrame && pSectFrame->IsSctFrame() ) + assert(pSectFrame->IsSctFrame()); { SwFrameDeleteGuard aDeleteGuard(&_rAnchorTextFrame); // #i44049# @@ -871,10 +896,9 @@ void SwObjectFormatterTextFrame::FormatAnchorFrameAndItsPrevs( SwTextFrame& _rAn // #i40140# - if anchor frame is inside a column, // format the content of the previous columns. // Note: It's a very simple format without formatting objects. - SwFrame* pColFrameOfAnchor = _rAnchorTextFrame.FindColFrame(); - SAL_WARN_IF(pColFrameOfAnchor && _rAnchorTextFrame.IsInFootnote(), "sw.layout", "tdf#122894 skipping anchor in column in footnote"); - if (pColFrameOfAnchor && !_rAnchorTextFrame.IsInFootnote()) + if (pColFrameOfAnchor) { + assert(pColFrameOfAnchor->IsColumnFrame()); // #i44049# _rAnchorTextFrame.LockJoin(); SwFrameDeleteGuard aDeleteGuard(&_rAnchorTextFrame);