editeng/source/editeng/editview.cxx |   47 ++++++++++++++++++++++++++++++++++++
 include/editeng/editview.hxx        |    8 ++++++
 sc/source/ui/app/inputhdl.cxx       |   24 +++++++++++++-----
 sc/source/ui/app/inputwin.cxx       |   10 ++++---
 sc/source/ui/inc/inputhdl.hxx       |    2 -
 5 files changed, 79 insertions(+), 12 deletions(-)

New commits:
commit a5ddcc1059ee3a5ac8fed526f5e1ceca51d32bc3
Author:     Szymon Kłos <szymon.k...@collabora.com>
AuthorDate: Wed Jan 25 14:39:34 2023 +0100
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Wed Feb 1 20:23:15 2023 +0000

    lok: formulabar: fix URL fields selection
    
    field is calculated as 1 character by selection getter
    let's unfold fields and send real length
    
    Change-Id: I557f8785a4d2ee6a41c6c95f4551f5e104a58c02
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146350
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Andras Timar <andras.ti...@collabora.com>

diff --git a/editeng/source/editeng/editview.cxx 
b/editeng/source/editeng/editview.cxx
index 9fc8514d7812..c522201ff917 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -1398,6 +1398,53 @@ const SvxFieldData* EditView::GetFieldAtCursor() const
     return pFieldItem ? pFieldItem->GetField() : nullptr;
 }
 
+sal_Int32 EditView::countFieldsOffsetSum(sal_Int32 nPara, sal_Int32 nPos, bool 
bCanOverflow) const
+{
+    if (!pImpEditView || !pImpEditView->pEditEngine)
+        return 0;
+
+    int nOffset = 0;
+
+    for (int nCurrentPara = 0; nCurrentPara <= nPara; nCurrentPara++)
+    {
+        int nFields = pImpEditView->pEditEngine->GetFieldCount( nCurrentPara );
+        for (int nField = 0; nField < nFields; nField++)
+        {
+            EFieldInfo aFieldInfo
+                = pImpEditView->pEditEngine->GetFieldInfo( nCurrentPara, 
nField );
+
+            bool bLastPara = nCurrentPara == nPara;
+            sal_Int32 nFieldPos = aFieldInfo.aPosition.nIndex;
+
+            if (bLastPara && nFieldPos >= nPos)
+                break;
+
+            sal_Int32 nFieldLen = aFieldInfo.aCurrentText.getLength();
+
+            // position in the middle of a field
+            if (!bCanOverflow && bLastPara && nFieldPos + nFieldLen > nPos)
+                nFieldLen = nPos - nFieldPos;
+
+            nOffset += nFieldLen - 1;
+        }
+    }
+
+    return nOffset;
+}
+
+sal_Int32 EditView::GetPosNoField(sal_Int32 nPara, sal_Int32 nPos) const
+{
+    sal_Int32 nOffset = countFieldsOffsetSum(nPara, nPos, false);
+    assert(nPos >= nOffset);
+    return nPos - nOffset;
+}
+
+sal_Int32 EditView::GetPosWithField(sal_Int32 nPara, sal_Int32 nPos) const
+{
+    sal_Int32 nOffset = countFieldsOffsetSum(nPara, nPos, true);
+    return nPos + nOffset;
+}
+
 void EditView::SetInvalidateMore( sal_uInt16 nPixel )
 {
     pImpEditView->SetInvalidateMore( nPixel );
diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx
index 1a9e2ed8afc9..02a120cc9b07 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -162,6 +162,10 @@ private:
                     EditView( const EditView& ) = delete;
     EditView&       operator=( const EditView& ) = delete;
 
+    // counts how many characters take unfolded fields
+    // bCanOverflow - count field length without trim to the selected pos
+    sal_Int32       countFieldsOffsetSum(sal_Int32 nPara, sal_Int32 nPo, bool 
bCanOverflow) const;
+
 public:
                     EditView( EditEngine* pEng, vcl::Window* pWindow );
                     ~EditView();
@@ -318,6 +322,10 @@ public:
     /// Select and return the field at the current cursor position
     const SvxFieldData* GetFieldAtCursor() const;
     void SelectFieldAtCursor();
+    /// Converts position in paragraph to logical position without unfolding 
fields
+    sal_Int32       GetPosNoField(sal_Int32 nPara, sal_Int32 nPos) const;
+    /// Converts logical position in paragraph to position with unfolded fields
+    sal_Int32       GetPosWithField(sal_Int32 nPara, sal_Int32 nPos) const;
 
     void            SetInvalidateMore( sal_uInt16 nPixel );
     sal_uInt16      GetInvalidateMore() const;
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 155b5a1e9a6e..1ea255f23207 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -1798,13 +1798,23 @@ void ScInputHandler::LOKPasteFunctionData(const 
OUString& rFunctionName)
     }
 }
 
-void ScInputHandler::LOKSendFormulabarUpdate(const SfxViewShell* pActiveViewSh,
+void ScInputHandler::LOKSendFormulabarUpdate(EditView* pActiveView,
+                                             const SfxViewShell* pActiveViewSh,
                                              const OUString& rText,
                                              const ESelection& rSelection)
 {
-    OUString aSelection =
-        OUString::number(rSelection.nStartPos) + ";" + 
OUString::number(rSelection.nEndPos) + ";" +
-        OUString::number(rSelection.nStartPara) + ";" + 
OUString::number(rSelection.nEndPara);
+    OUString aSelection;
+    if (pActiveView)
+    {
+        aSelection = OUString::number(pActiveView->GetPosWithField(0, 
rSelection.nStartPos)) + ";" +
+            OUString::number(pActiveView->GetPosWithField(0, 
rSelection.nEndPos)) + ";" +
+            OUString::number(rSelection.nStartPara) + ";" + 
OUString::number(rSelection.nEndPara);
+    }
+    else
+    {
+        aSelection = OUString::number(rSelection.nStartPos) + ";" + 
OUString::number(rSelection.nEndPos) + ";" +
+            OUString::number(rSelection.nStartPara) + ";" + 
OUString::number(rSelection.nEndPara);
+    }
 
     std::unique_ptr<jsdialog::ActionDataMap> pData = 
std::make_unique<jsdialog::ActionDataMap>();
     (*pData)["action_type"] = "setText";
@@ -2793,7 +2803,7 @@ void ScInputHandler::DataChanged( bool bFromTopNotify, 
bool bSetModified )
         if (pActiveView)
             aSel = pActiveView->GetSelection();
 
-        ScInputHandler::LOKSendFormulabarUpdate(pActiveViewSh,
+        ScInputHandler::LOKSendFormulabarUpdate(pActiveView, pActiveViewSh,
                                                 
ScEditUtil::GetMultilineString(*mpEditEngine),
                                                 aSel);
     }
@@ -4269,7 +4279,7 @@ void ScInputHandler::NotifyChange( const ScInputHdlState* 
pState,
                         if (aSel.nEndPara == EE_PARA_NOT_FOUND)
                             aSel.nEndPara = 0;
 
-                        ScInputHandler::LOKSendFormulabarUpdate(pActiveViewSh, 
aString, aSel);
+                        ScInputHandler::LOKSendFormulabarUpdate(pActiveView, 
pActiveViewSh, aString, aSel);
                         // TODO: deprecated?
                         
pActiveViewSh->libreOfficeKitViewCallback(LOK_CALLBACK_CELL_FORMULA, 
aString.toUtf8().getStr());
                     }
@@ -4433,7 +4443,7 @@ void ScInputHandler::InputSelection( const EditView* 
pView )
     {
         EditView* pActiveView = pTopView ? pTopView : pTableView;
         ESelection aSel = pActiveView ? pActiveView->GetSelection() : 
ESelection();
-        ScInputHandler::LOKSendFormulabarUpdate(pActiveViewSh, 
GetEditString(), aSel);
+        ScInputHandler::LOKSendFormulabarUpdate(pActiveView, pActiveViewSh, 
GetEditString(), aSel);
     }
 }
 
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index 1122efc5debe..85b9bff669d1 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -1102,7 +1102,7 @@ ScTextWndGroup::ScTextWndGroup(ScInputBarGroup& rParent, 
ScTabViewShell* pViewSh
 {
     mxScrollWin->connect_vadjustment_changed(LINK(this, ScTextWndGroup, 
Impl_ScrollHdl));
     if (comphelper::LibreOfficeKit::isActive())
-        ScInputHandler::LOKSendFormulabarUpdate(SfxViewShell::Current(), "", 
ESelection());
+        ScInputHandler::LOKSendFormulabarUpdate(nullptr, 
SfxViewShell::Current(), "", ESelection());
 }
 
 Point ScTextWndGroup::GetCursorScreenPixelPos(bool bBelow)
@@ -1753,8 +1753,10 @@ bool ScTextWnd::Command( const CommandEvent& rCEvt )
         {
             nParaStart = pParaPoint ? pParaPoint->X() : 0;
             nParaEnd = pParaPoint ? pParaPoint->Y() : 0;
-            nPosStart = aSelectionStartEnd.X();
-            nPosEnd = aSelectionStartEnd.Y();
+            nPosStart = m_xEditView->GetPosNoField(nParaStart, 
aSelectionStartEnd.X());
+            nPosEnd = m_xEditView->GetPosNoField(nParaEnd, 
aSelectionStartEnd.Y());
+
+
         }
 
         m_xEditView->SetSelection(ESelection(nParaStart, nPosStart, nParaEnd, 
nPosEnd));
@@ -1996,7 +1998,7 @@ void ScTextWnd::SetTextString( const OUString& rNewString 
)
     if (comphelper::LibreOfficeKit::isActive())
     {
         ESelection aSel = m_xEditView ? m_xEditView->GetSelection() : 
ESelection();
-        ScInputHandler::LOKSendFormulabarUpdate(SfxViewShell::Current(), 
rNewString, aSel);
+        ScInputHandler::LOKSendFormulabarUpdate(m_xEditView.get(), 
SfxViewShell::Current(), rNewString, aSel);
     }
 
     SetScrollBarRange();
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
index 56ed3bb95b1f..be806c707d8f 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -300,7 +300,7 @@ public:
                                     tools::Long nTab, const Color& rColor );
 
     void            LOKPasteFunctionData(const OUString& rFunctionName);
-    static void     LOKSendFormulabarUpdate(const SfxViewShell* pActiveViewSh,
+    static void     LOKSendFormulabarUpdate(EditView* pEditView, const 
SfxViewShell* pActiveViewSh,
                                             const OUString& rText, const 
ESelection& rSelection);
 };
 

Reply via email to