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 7a40e908d45007bbc8a162840e7a7f6d538e0c87
Author:     Szymon Kłos <szymon.k...@collabora.com>
AuthorDate: Wed Jan 25 14:39:34 2023 +0100
Commit:     Szymon Kłos <szymon.k...@collabora.com>
CommitDate: Mon Feb 6 15:02:10 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>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146578
    Tested-by: Szymon Kłos <szymon.k...@collabora.com>
    Reviewed-by: Szymon Kłos <szymon.k...@collabora.com>

diff --git a/editeng/source/editeng/editview.cxx 
b/editeng/source/editeng/editview.cxx
index 4096e0e18bf8..f243d6d8feb6 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -1394,6 +1394,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 17ed1bb4e7ac..73d4c23f49a9 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -160,6 +160,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();
@@ -316,6 +320,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 75655d807b73..f80b6c1b49a8 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -1781,13 +1781,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";
@@ -2775,7 +2785,7 @@ void ScInputHandler::DataChanged( bool bFromTopNotify, 
bool bSetModified )
         if (pActiveView)
             aSel = pActiveView->GetSelection();
 
-        ScInputHandler::LOKSendFormulabarUpdate(pActiveViewSh,
+        ScInputHandler::LOKSendFormulabarUpdate(pActiveView, pActiveViewSh,
                                                 
ScEditUtil::GetMultilineString(*mpEditEngine),
                                                 aSel);
     }
@@ -4248,7 +4258,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());
                     }
@@ -4412,7 +4422,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 14249fe2eb04..039d5b97ffa1 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -1133,7 +1133,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)
@@ -1800,8 +1800,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));
@@ -2043,7 +2045,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 1506a0c2a2b3..90a562f6c11f 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -295,7 +295,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