sw/source/core/text/itrcrsr.cxx |   54 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 6 deletions(-)

New commits:
commit 4db49918efa3ae13a74d8a1450f10fb25393ce86
Author:     Michael Stahl <[email protected]>
AuthorDate: Fri Oct 27 16:18:44 2023 +0200
Commit:     Caolán McNamara <[email protected]>
CommitDate: Mon Nov 6 10:20:46 2023 +0100

    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 <[email protected]>
    (cherry picked from commit 468e5b8e0a7fefe1ca53faeb15f5f6527c37a268)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158810
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index 80900061b66f..431aeea2734d 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -1527,7 +1527,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())
     {
@@ -1757,18 +1761,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 );

Reply via email to