sw/source/core/text/itrcrsr.cxx | 58 ++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 17 deletions(-)
New commits: commit 97dcffe188f0dec4dbd0af894fe7739e1a2abcbb Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Tue Jul 30 18:03:10 2024 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Wed Jul 31 15:41:43 2024 +0200 tdf#162035 sw: fix crash with field in SwMultiPortion SwTextCursor::GetModelPositionForViewPoint() is recursive for SwMultiPortions, overriding m_pCurr via SwTextCursorSave, so the SwSpecialPos counting code needs to be recursive too. (regression from commit 468e5b8e0a7fefe1ca53faeb15f5f6527c37a268) Change-Id: Ic3f2f359a21dcae692400efdd693cc4042f9426e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171247 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx index 6ae65945520e..0affcfcd96d1 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -1330,6 +1330,46 @@ static bool ConsiderNextPortionForCursorOffset(const SwLinePortion* pPor, SwTwip return true; } +static auto SearchLine(SwLineLayout const*const pLineOfFoundPor, + SwLinePortion const*const pFoundPor, + int & rLines, std::vector<SwFieldPortion const*> & rPortions, + SwLineLayout const*const pLine) -> bool +{ + for (SwLinePortion const* pLP = pLine; pLP; pLP = pLP->GetNextPortion()) + { + if (pLP == pFoundPor) + { + return true; + } + if (pLP->InFieldGrp()) + { + SwFieldPortion const* pField(static_cast<SwFieldPortion const*>(pLP)); + if (!pField->IsFollow()) + { + rLines = 0; + rPortions.clear(); + } + if (pLine == pLineOfFoundPor) + { + rPortions.emplace_back(pField); + } + } + else if (pLP->IsMultiPortion()) + { + SwMultiPortion const*const pMulti(static_cast<SwMultiPortion const*>(pLP)); + for (SwLineLayout const* pMLine = &pMulti->GetRoot(); + pMLine; pMLine = pMLine->GetNext()) + { + if (SearchLine(pLineOfFoundPor, pFoundPor, rLines, rPortions, pMLine)) + { + return true; + } + } + } + } + return (pLine == pLineOfFoundPor); +} + // Return: Offset in String TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, const Point &rPoint, bool bChgNode, SwCursorMoveState* pCMS ) const @@ -1780,23 +1820,7 @@ TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con for (SwLineLayout const* pLine = GetInfo().GetParaPortion(); true; pLine = pLine->GetNext()) { - for (SwLinePortion const* pLP = pLine; pLP && pLP != pPor; pLP = pLP->GetNextPortion()) - { - if (pLP->InFieldGrp()) - { - SwFieldPortion const* pField(static_cast<SwFieldPortion const*>(pLP)); - if (!pField->IsFollow()) - { - nLines = 0; - portions.clear(); - } - if (pLine == m_pCurr) - { - portions.emplace_back(pField); - } - } - } - if (pLine == m_pCurr) + if (SearchLine(m_pCurr, pPor, nLines, portions, pLine)) { break; }