editeng/source/editeng/impedit2.cxx |   28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

New commits:
commit 9c40875c78413e543a261b9ad350c6536fd91215
Author:     Attila Szűcs <[email protected]>
AuthorDate: Fri Jan 30 04:39:49 2026 +0100
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Mon Feb 2 17:14:34 2026 +0100

    tdf#159861 editeng: fix cursor at multiline hyperlinks
    
    fix for cursor position calcualtions in editengine,
    in case of multiline hyperlinks.
    
    The original problem is that the wordwrapping
    of editengine create lines where a hyperlink
    is just 1 symbol, so it can only be in 1 line.
    There was a hack to calculate special data for fields,
    and wrap hyperlink with a separate algorithm.
    and the paint was hakced to display it.
    But in edit mode it was displayed only in 1 line without any wrapping.
    
    After the improvement at Bug 154248, hyperlinks was diplayed
    in edit mode in the same way as in not edit mode,
    but the cursor was not improved the same way.
    
    Now cursor position has the same hack in its calculations
    as the display have.
    
    There are still glitches around it.
    as it is actually a new feature,
    and not implemented everything that would be needed.
    
    Change-Id: Iace97972268a0d0e5f323f9b111ccfcef41adf7c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198392
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Stephan Bergmann <[email protected]>

diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index 181622471a31..c043eff94e4a 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -3174,6 +3174,7 @@ void ImpEditEngine::IterateLineAreas(const 
IterateLinesAreasFunc& f, IterFlag eO
     const tools::Long nVertLineSpacing = CalcVertLineSpacing(aLineStart);
     const tools::Long nColumnWidth = GetColumnWidth(maPaperSize);
     sal_Int16 nColumn = 0;
+    sal_Int32 nUrlYHack = 0;
     for (sal_Int32 n = 0, nPortions = GetParaPortions().Count(); n < 
nPortions; ++n)
     {
         ParaPortion& rPortion = GetParaPortions().getRef(n);
@@ -3217,6 +3218,33 @@ void ImpEditEngine::IterateLineAreas(const 
IterateLinesAreasFunc& f, IterFlag eO
                     nLineHeight += nVertLineSpacing;
                 MoveToNextLine(aLineStart, nLineHeight, nColumn, aOrigin,
                                &aInfo.nHeightNeededToNotWrap);
+
+                // Position the actual line some lines down,
+                // if the previous line ended with a multiline hyperlink
+                if (nUrlYHack != 0)
+                {
+                    MoveToNextLine(aLineStart, nUrlYHack, nColumn, aOrigin);
+                    nUrlYHack = 0;
+                }
+
+                // Check if this line has a textportion with a multiline 
hyperlink
+                // then the next line should be positioned further away
+                for (sal_Int32 nPortion = rLine.GetStartPortion();
+                     nPortion <= rLine.GetEndPortion(); nPortion++)
+                {
+                    const TextPortion& rTextPortion = 
rPortion.GetTextPortions()[nPortion];
+                    if (rTextPortion.GetKind() == PortionKind::FIELD)
+                    {
+                        ExtraPortionInfo* pExtraInfo = 
rTextPortion.GetExtraInfos();
+                        if (pExtraInfo && pExtraInfo->lineBreaksList.size() > 
2)
+                        {
+                            // Use the same size calculation as in 
ImpEditEngine::Paint
+                            const sal_uInt16 nMaxAscent(rLine.GetMaxAscent());
+                            nUrlYHack = nMaxAscent * 
(pExtraInfo->lineBreaksList.size() - 2);
+                        }
+                    }
+                }
+
                 const bool bInclILS = eOptions & IterFlag::inclILS;
                 if (bInclILS && (nLine != nLines - 1) && 
!maStatus.IsOutliner())
                 {

Reply via email to