summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2023-10-27 16:18:44 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2023-11-02 10:39:12 +0100
commit468e5b8e0a7fefe1ca53faeb15f5f6527c37a268 (patch)
tree2e7d32fb2be9d2e52e39fa73f204e74e85bdec49 /sw
parenta2f298adf5b6aae54bd9c20a7fbfd007dd356617 (diff)
tdf#157816 sw: fix getting position in field portion follow
SwSpecialPos can be used to get index inside a field, but SwTextCursor::GetModelPositionForViewPoint() has several problems: * the field portion follow has length 0 so an early return is taken * the nCharOfst is set to the index in the portion, but it needs to also count preceding portions of the same field in the line, and nLineOfst needs to be set as well, because the SwPosition corresponds to the start of the field * m_bFieldInfo must be set to guarantee SwPosition before the field in the nLenght==0 branch, but then there are 2 branches that first set nLength=0 and then decrement it, resulting in a SwPosition 1 char before the field. Change-Id: Ib7d30981e41b40f4c068fa6d84211c000ecde753 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158570 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/text/itrcrsr.cxx54
1 files changed, 48 insertions, 6 deletions
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index 3dea5b461c44..7a7024d97a09 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -1528,7 +1528,11 @@ TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con
--nCurrStart;
}
}
- return nCurrStart;
+ if (!pPor->InFieldGrp() || !static_cast<SwFieldPortion const*>(pPor)->IsFollow()
+ || !pCMS || !pCMS->m_pSpecialPos)
+ {
+ return nCurrStart;
+ }
}
if (TextFrameIndex(1) == nLength || pPor->InFieldGrp())
{
@@ -1758,18 +1762,56 @@ TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, con
if ( pPor->InFieldGrp() && pCMS && pCMS->m_pSpecialPos )
{
pCMS->m_pSpecialPos->nCharOfst = sal_Int32(nLength);
+ // follow portions: need to add the length of all previous
+ // portions for the same field
+ if (static_cast<SwFieldPortion const*>(pPor)->IsFollow())
+ {
+ int nLines(0);
+ std::vector<SwFieldPortion const*> portions;
+ 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)
+ {
+ break;
+ }
+ ++nLines;
+ }
+ for (SwFieldPortion const* pField : portions)
+ {
+ pCMS->m_pSpecialPos->nCharOfst += pField->GetExp().getLength();
+ }
+ pCMS->m_pSpecialPos->nLineOfst = nLines;
+ }
nLength = TextFrameIndex(0);
}
+ else if (bFieldInfo && nLength == pPor->GetLen() &&
+ (! pPor->GetNextPortion() ||
+ ! pPor->GetNextPortion()->IsPostItsPortion()))
+ {
+ --nLength;
+ }
// set cursor bidi level
if ( pCMS )
pCMS->m_nCursorBidiLevel =
aDrawInf.GetCursorBidiLevel();
-
- if( bFieldInfo && nLength == pPor->GetLen() &&
- ( ! pPor->GetNextPortion() ||
- ! pPor->GetNextPortion()->IsPostItsPortion() ) )
- --nLength;
}
if( nOldProp )
const_cast<SwFont*>(GetFnt())->SetProportion( nOldProp );