sc/source/ui/app/inputhdl.cxx |   45 ++++++++++++++++++++++++++++++------------
 sc/source/ui/app/inputwin.cxx |   12 +++++++----
 sc/source/ui/inc/inputhdl.hxx |    2 -
 sc/source/ui/inc/tabvwsh.hxx  |   20 +++++++++++++++++-
 4 files changed, 60 insertions(+), 19 deletions(-)

New commits:
commit c0df28f957b43f0ecbffdc994ee0702dbe5bc33f
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue Nov 14 17:24:18 2023 +0000
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Wed Nov 15 11:08:06 2023 +0100

    merge duplicate formula bar updates in close time proximity
    
    We get three updates per keystroke, StartExtTextInput, ExtTextInput and
    PostExtTextInput.  Skip duplicate updates. Be conservative and don't
    skip duplicates that are 5+ seconds apart.
    
    Change-Id: I501bff4193528fa9263d296700d64e2f60b52222
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159433
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 769f4249a4bf..7f75604dc464 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -1806,8 +1806,7 @@ void ScInputHandler::LOKPasteFunctionData(const OUString& 
rFunctionName)
     }
 }
 
-void ScInputHandler::LOKSendFormulabarUpdate(EditView* pActiveView,
-                                             const SfxViewShell* pActiveViewSh,
+void ScTabViewShell::LOKSendFormulabarUpdate(EditView* pActiveView,
                                              const OUString& rText,
                                              const ESelection& rSelection)
 {
@@ -1824,13 +1823,35 @@ void ScInputHandler::LOKSendFormulabarUpdate(EditView* 
pActiveView,
             OUString::number(rSelection.nStartPara) + ";" + 
OUString::number(rSelection.nEndPara);
     }
 
+    sal_uInt64 nCurrentShellId = reinterpret_cast<sal_uInt64>(this);
+
+    // We can get three updates per keystroke, StartExtTextInput, ExtTextInput 
and PostExtTextInput
+    // Skip duplicate updates. Be conservative and don't skip duplicates that 
are 5+ seconds
+    // apart.
+    std::chrono::steady_clock::time_point now = 
std::chrono::steady_clock::now();
+    if (maSendFormulabarUpdate.m_nShellId == nCurrentShellId &&
+        maSendFormulabarUpdate.m_aText == rText &&
+        maSendFormulabarUpdate.m_aSelection == aSelection &&
+        std::chrono::duration_cast<std::chrono::seconds>(
+            now - maSendFormulabarUpdate.m_nTimeStamp) < 
std::chrono::seconds(5))
+    {
+        return;
+    }
+
+    maSendFormulabarUpdate.m_nShellId = nCurrentShellId;
+    maSendFormulabarUpdate.m_aText = rText;
+    maSendFormulabarUpdate.m_aSelection = aSelection;
+    maSendFormulabarUpdate.m_nTimeStamp = now;
+    maSendFormulabarUpdate.Send();
+}
+
+void ScTabViewShell::SendFormulabarUpdate::Send()
+{
     std::unique_ptr<jsdialog::ActionDataMap> pData = 
std::make_unique<jsdialog::ActionDataMap>();
     (*pData)["action_type"] = "setText";
-    (*pData)["text"] = rText;
-    (*pData)["selection"] = aSelection;
-
-    sal_uInt64 nCurrentShellId = reinterpret_cast<sal_uInt64>(pActiveViewSh);
-    OUString sWindowId = OUString::number(nCurrentShellId) + "formulabar";
+    (*pData)["text"] = m_aText;
+    (*pData)["selection"] = m_aSelection;
+    OUString sWindowId = OUString::number(m_nShellId) + "formulabar";
     jsdialog::SendAction(sWindowId, "sc_input_window", std::move(pData));
 }
 
@@ -2815,9 +2836,9 @@ void ScInputHandler::DataChanged( bool bFromTopNotify, 
bool bSetModified )
         if (pActiveView)
             aSel = pActiveView->GetSelection();
 
-        ScInputHandler::LOKSendFormulabarUpdate(pActiveView, pActiveViewSh,
-                                                
ScEditUtil::GetMultilineString(*mpEditEngine),
-                                                aSel);
+        pActiveViewSh->LOKSendFormulabarUpdate(pActiveView,
+                                               
ScEditUtil::GetMultilineString(*mpEditEngine),
+                                               aSel);
     }
 
     UpdateFormulaMode();
@@ -4295,7 +4316,7 @@ void ScInputHandler::NotifyChange( const ScInputHdlState* 
pState,
                         if (aSel.nEndPara == EE_PARA_NOT_FOUND)
                             aSel.nEndPara = 0;
 
-                        ScInputHandler::LOKSendFormulabarUpdate(pActiveView, 
pActiveViewSh, aString, aSel);
+                        pActiveViewSh->LOKSendFormulabarUpdate(pActiveView, 
aString, aSel);
                         // TODO: deprecated?
                         
pActiveViewSh->libreOfficeKitViewCallback(LOK_CALLBACK_CELL_FORMULA, 
aString.toUtf8());
                     }
@@ -4459,7 +4480,7 @@ void ScInputHandler::InputSelection( const EditView* 
pView )
     {
         EditView* pActiveView = pTopView ? pTopView : pTableView;
         ESelection aSel = pActiveView ? pActiveView->GetSelection() : 
ESelection();
-        ScInputHandler::LOKSendFormulabarUpdate(pActiveView, pActiveViewSh, 
GetEditString(), aSel);
+        pActiveViewSh->LOKSendFormulabarUpdate(pActiveView, GetEditString(), 
aSel);
     }
 }
 
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index 945a1d8973cc..7f0cf742b05d 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -1168,8 +1168,11 @@ ScTextWndGroup::ScTextWndGroup(ScInputBarGroup& rParent, 
ScTabViewShell* pViewSh
     , mrParent(rParent)
 {
     mxScrollWin->connect_vadjustment_changed(LINK(this, ScTextWndGroup, 
Impl_ScrollHdl));
-    if (comphelper::LibreOfficeKit::isActive())
-        ScInputHandler::LOKSendFormulabarUpdate(nullptr, 
SfxViewShell::Current(), "", ESelection());
+    if (ScTabViewShell* pActiveViewShell = 
comphelper::LibreOfficeKit::isActive() ?
+            dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()) : nullptr)
+    {
+        pActiveViewShell->LOKSendFormulabarUpdate(nullptr, "", ESelection());
+    }
 }
 
 Point ScTextWndGroup::GetCursorScreenPixelPos(bool bBelow)
@@ -2070,10 +2073,11 @@ void ScTextWnd::SetTextString( const OUString& 
rNewString, bool bKitUpdate )
         bInputMode = false;
     }
 
-    if (bKitUpdate && comphelper::LibreOfficeKit::isActive())
+    if (ScTabViewShell* pActiveViewShell = bKitUpdate && 
comphelper::LibreOfficeKit::isActive() ?
+            dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()) : nullptr)
     {
         ESelection aSel = m_xEditView ? m_xEditView->GetSelection() : 
ESelection();
-        ScInputHandler::LOKSendFormulabarUpdate(m_xEditView.get(), 
SfxViewShell::Current(), rNewString, aSel);
+        pActiveViewShell->LOKSendFormulabarUpdate(m_xEditView.get(), 
rNewString, aSel);
     }
 
     SetScrollBarRange();
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
index 90a562f6c11f..3067dd819397 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -295,8 +295,6 @@ public:
                                     tools::Long nTab, const Color& rColor );
 
     void            LOKPasteFunctionData(const OUString& rFunctionName);
-    static void     LOKSendFormulabarUpdate(EditView* pEditView, const 
SfxViewShell* pActiveViewSh,
-                                            const OUString& rText, const 
ESelection& rSelection);
 };
 
 //  ScInputHdlState
diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx
index 53b093695297..cc52a84f8354 100644
--- a/sc/source/ui/inc/tabvwsh.hxx
+++ b/sc/source/ui/inc/tabvwsh.hxx
@@ -91,9 +91,26 @@ enum ObjectSelectionType
 };
 
 class ScFormEditData;
-class SC_DLLPUBLIC ScTabViewShell: public SfxViewShell, public ScDBFunc
+class SC_DLLPUBLIC ScTabViewShell : public SfxViewShell, public ScDBFunc
 {
 private:
+    struct SendFormulabarUpdate
+    {
+        OUString m_aText;
+        OUString m_aSelection;
+        sal_uInt64 m_nShellId;
+        std::chrono::steady_clock::time_point m_nTimeStamp;
+
+        SendFormulabarUpdate()
+            : m_nShellId(0)
+        {
+        }
+
+        void Send();
+    };
+
+    SendFormulabarUpdate maSendFormulabarUpdate;
+
     ObjectSelectionType     eCurOST;
     sal_uInt16              nDrawSfxId;
     SdrObjKind              eFormObjKind;
@@ -405,6 +422,7 @@ public:
     /// is equal to nCurrentTabIndex
     static void notifyAllViewsSheetGeomInvalidation(const SfxViewShell* 
pForViewShell, bool bColumns, bool bRows, bool bSizes,
                                                     bool bHidden, bool 
bFiltered, bool bGroups, SCTAB nCurrentTabIndex);
+    void LOKSendFormulabarUpdate(EditView* pEditView, const OUString& rText, 
const ESelection& rSelection);
     css::uno::Reference<css::drawing::XShapes> getSelectedXShapes();
     static  css::uno::Reference<css::datatransfer::XTransferable2> 
GetClipData(vcl::Window* pWin);
 

Reply via email to