include/vcl/jsdialog/executor.hxx    |   24 +++++++
 include/vcl/weld.hxx                 |    2 
 sc/inc/sc.hrc                        |    3 
 sc/sdi/cellsh.sdi                    |    2 
 sc/sdi/scalc.sdi                     |   37 +++++++++++
 sc/source/ui/app/inputhdl.cxx        |   44 +++++++++++++
 sc/source/ui/app/inputwin.cxx        |  115 ++++++++++++++++++++++-------------
 sc/source/ui/inc/inputhdl.hxx        |    2 
 sc/source/ui/inc/inputwin.hxx        |    1 
 sc/source/ui/view/cellsh1.cxx        |   17 ++++-
 sc/source/ui/view/cellsh3.cxx        |   17 +++++
 vcl/inc/jsdialog/jsdialogbuilder.hxx |   30 +++++----
 vcl/jsdialog/executor.cxx            |   42 ++++++++++++
 vcl/jsdialog/jsdialogbuilder.cxx     |   19 +++--
 14 files changed, 293 insertions(+), 62 deletions(-)

New commits:
commit 7df8334b0078b4e8f8fbf5c55d9fdc54398b57b7
Author:     Szymon Kłos <[email protected]>
AuthorDate: Thu Apr 14 12:09:38 2022 +0200
Commit:     Szymon Kłos <[email protected]>
CommitDate: Sun May 1 20:18:52 2022 +0200

    jsdialog: handle formulabar as textinput
    
    mostly boilerplate code
    
    jsdialog changes:
    - added force parameter to sendAction
    - added support for key press/release and command events
    - moved ActionDataMap to jsdialog namespace for sharing
    
    formulabar changes:
    - added calls to send jsdialog messages with formula
    - added cursor moving support - on command event
    
    Change-Id: I714715133901941ba0758655e2d5907a3bae79f2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133010
    Reviewed-by: Mert Tumer <[email protected]>
    Tested-by: Szymon Kłos <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133652
    Tested-by: Jenkins
    Reviewed-by: Szymon Kłos <[email protected]>

diff --git a/include/vcl/jsdialog/executor.hxx 
b/include/vcl/jsdialog/executor.hxx
index 0f8fb821e2bd..6e388a6a3f79 100644
--- a/include/vcl/jsdialog/executor.hxx
+++ b/include/vcl/jsdialog/executor.hxx
@@ -12,6 +12,7 @@
 #include <vcl/dllapi.h>
 #include <vcl/uitest/uiobject.hxx>
 #include <vcl/weld.hxx>
+#include <unordered_map>
 
 class LOKTrigger
 {
@@ -56,13 +57,36 @@ public:
     }
 
     static void trigger_closed(weld::Popover& rPopover) { rPopover.popdown(); }
+
+    static void trigger_key_press(weld::Widget& rWidget, const KeyEvent& 
rEvent)
+    {
+        rWidget.m_aKeyPressHdl.Call(rEvent);
+    }
+
+    static void trigger_key_release(weld::Widget& rWidget, const KeyEvent& 
rEvent)
+    {
+        rWidget.m_aKeyReleaseHdl.Call(rEvent);
+    }
+
+    static void command(weld::DrawingArea& rArea, const CommandEvent& rCmd)
+    {
+        rArea.m_aCommandHdl.Call(rCmd);
+    }
 };
 
 namespace jsdialog
 {
+// type used to store key-value pairs to put in the generated messages
+typedef std::unordered_map<std::string, OUString> ActionDataMap;
+
+/// execute action on a widget
 VCL_DLLPUBLIC bool ExecuteAction(const std::string& nWindowId, const OString& 
rWidget,
                                  StringMap& rData);
+/// send full update message to the client
 VCL_DLLPUBLIC void SendFullUpdate(const std::string& nWindowId, const OString& 
rWidget);
+/// send action message to the client
+VCL_DLLPUBLIC void SendAction(const std::string& nWindowId, const OString& 
rWidget,
+                              std::unique_ptr<ActionDataMap> pData);
 VCL_DLLPUBLIC StringMap jsonToStringMap(const char* pJSON);
 };
 
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 226e2cb6c21a..06cb4d037b3b 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -79,6 +79,8 @@ class DialogController;
 
 class VCL_DLLPUBLIC Widget
 {
+    friend class ::LOKTrigger;
+
 protected:
     Link<Widget&, void> m_aFocusInHdl;
     Link<Widget&, void> m_aFocusOutHdl;
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index f7a41b13d084..a1b7afa38976 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -50,6 +50,7 @@
 #include <unotools/localedatawrapper.hxx>
 #include <unotools/charclass.hxx>
 #include <vcl/help.hxx>
+#include <vcl/jsdialog/executor.hxx>
 #include <vcl/commandevent.hxx>
 #include <vcl/cursor.hxx>
 #include <vcl/settings.hxx>
@@ -1784,6 +1785,23 @@ void ScInputHandler::LOKPasteFunctionData(const 
OUString& rFunctionName)
     }
 }
 
+void ScInputHandler::LOKSendFormulabarUpdate(const SfxViewShell* pActiveViewSh,
+                                             const OUString& rText,
+                                             const ESelection& rSelection)
+{
+    OUString aSelection =
+        OUString::number(rSelection.nStartPos) + ";" + 
OUString::number(rSelection.nEndPos);
+
+    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);
+    std::string sWindowId = std::to_string(nCurrentShellId) + "formulabar";
+    jsdialog::SendAction(sWindowId, "sc_input_window", std::move(pData));
+}
+
 // Calculate selection and display as tip help
 static OUString lcl_Calculate( const OUString& rFormula, ScDocument& rDoc, 
const ScAddress &rPos )
 {
@@ -2710,7 +2728,10 @@ void ScInputHandler::DataChanged( bool bFromTopNotify, 
bool bSetModified )
         if (comphelper::LibreOfficeKit::isActive())
         {
             if (pActiveViewSh)
+            {
+                // TODO: deprecated?
                 
pActiveViewSh->libreOfficeKitViewCallback(LOK_CALLBACK_CELL_FORMULA, 
aText.toUtf8().getStr());
+            }
         }
     }
 
@@ -2723,6 +2744,7 @@ void ScInputHandler::DataChanged( bool bFromTopNotify, 
bool bSetModified )
     mpEditEngine->QuickFormatDoc();
 
     EditView* pActiveView = pTopView ? pTopView : pTableView;
+    ESelection aSel;
     if (pActiveView && pActiveViewSh)
     {
         ScViewData& rViewData = pActiveViewSh->GetViewData();
@@ -2731,7 +2753,7 @@ void ScInputHandler::DataChanged( bool bFromTopNotify, 
bool bSetModified )
         if (!bNeedGrow)
         {
             // Cursor before the end?
-            ESelection aSel = pActiveView->GetSelection();
+            aSel = pActiveView->GetSelection();
             aSel.Adjust();
             bNeedGrow = ( aSel.nEndPos != 
mpEditEngine->GetTextLen(aSel.nEndPara) );
         }
@@ -2747,6 +2769,13 @@ void ScInputHandler::DataChanged( bool bFromTopNotify, 
bool bSetModified )
         }
     }
 
+    if (comphelper::LibreOfficeKit::isActive() && pActiveViewSh && pInputWin)
+    {
+        ScInputHandler::LOKSendFormulabarUpdate(pActiveViewSh,
+                                                
ScEditUtil::GetMultilineString(*mpEditEngine),
+                                                aSel);
+    }
+
     UpdateFormulaMode();
     bTextValid = false; // Changes only in the EditEngine
     bInOwnChange = false;
@@ -4188,7 +4217,13 @@ void ScInputHandler::NotifyChange( const 
ScInputHdlState* pState,
                         pInputWin->SetTextString(aString);
 
                     if (comphelper::LibreOfficeKit::isActive() && 
pActiveViewSh)
+                    {
+                        EditView* pActiveView = pTopView ? pTopView : 
pTableView;
+                        ESelection aSel = pActiveView ? 
pActiveView->GetSelection() : ESelection();
+                        ScInputHandler::LOKSendFormulabarUpdate(pActiveViewSh, 
aString, aSel);
+                        // TODO: deprecated?
                         
pActiveViewSh->libreOfficeKitViewCallback(LOK_CALLBACK_CELL_FORMULA, 
aString.toUtf8().getStr());
+                    }
                 }
 
                 if ( pInputWin || comphelper::LibreOfficeKit::isActive())      
                  // Named range input
@@ -4344,6 +4379,13 @@ void ScInputHandler::InputSelection( const EditView* 
pView )
 
     // When the selection is changed manually, stop overwriting parentheses
     ResetAutoPar();
+
+    if (comphelper::LibreOfficeKit::isActive() && pActiveViewSh)
+    {
+        EditView* pActiveView = pTopView ? pTopView : pTableView;
+        ESelection aSel = pActiveView ? pActiveView->GetSelection() : 
ESelection();
+        ScInputHandler::LOKSendFormulabarUpdate(pActiveViewSh, 
GetEditString(), aSel);
+    }
 }
 
 void ScInputHandler::InputChanged( const EditView* pView, bool bFromNotify )
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index 47c8c0fdb770..e50c682a1703 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -1115,6 +1115,8 @@ ScTextWndGroup::ScTextWndGroup(ScInputBarGroup& rParent, 
ScTabViewShell* pViewSh
     , mrParent(rParent)
 {
     mxScrollWin->connect_vadjustment_changed(LINK(this, ScTextWndGroup, 
Impl_ScrollHdl));
+    if (comphelper::LibreOfficeKit::isActive())
+        ScInputHandler::LOKSendFormulabarUpdate(SfxViewShell::Current(), "", 
ESelection());
 }
 
 Point ScTextWndGroup::GetCursorScreenPixelPos(bool bBelow)
@@ -1734,6 +1736,26 @@ bool ScTextWnd::Command( const CommandEvent& rCEvt )
             SC_MOD()->InputChanged( m_xEditView.get() );
     }
 
+    if ( comphelper::LibreOfficeKit::isActive() && nCommand == 
CommandEventId::CursorPos )
+    {
+        // LOK uses this to setup caret position because drawingarea is 
replaced
+        // with text input field, it sends logical caret position (start, end) 
not pixels
+
+        StartEditEngine();
+        TextGrabFocus();
+
+        if (!m_xEditView)
+            return true;
+
+        Point aSelectionStartEnd = rCEvt.GetMousePosPixel();
+        m_xEditView->SetSelection(ESelection(0, aSelectionStartEnd.X(),
+                                                0, aSelectionStartEnd.Y()));
+
+        SC_MOD()->InputSelection( m_xEditView.get() );
+
+        bConsumed = true;
+    }
+
     bInputMode = false;
 
     return bConsumed;
@@ -1889,6 +1911,12 @@ static sal_Int32 findFirstNonMatchingChar(const 
OUString& rStr1, const OUString&
 
 void ScTextWnd::SetTextString( const OUString& rNewString )
 {
+    if (comphelper::LibreOfficeKit::isActive())
+    {
+        ESelection aSel = m_xEditView ? m_xEditView->GetSelection() : 
ESelection();
+        ScInputHandler::LOKSendFormulabarUpdate(SfxViewShell::Current(), 
rNewString, aSel);
+    }
+
     // Ideally it would be best to create on demand the EditEngine/EditView 
here, but... for
     // the initialisation scenario where a cell is first clicked on we end up 
with the text in the
     // inputbar window scrolled to the bottom if we do that here ( because the 
tableview and topview
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
index 625d2f7ca1f8..7b06ee3320ed 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -294,6 +294,8 @@ public:
                                     tools::Long nTab, const Color& rColor );
 
     void            LOKPasteFunctionData(const OUString& rFunctionName);
+    static void     LOKSendFormulabarUpdate(const SfxViewShell* pActiveViewSh,
+                                            const OUString& rText, const 
ESelection& rSelection);
 };
 
 //  ScInputHdlState
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx 
b/vcl/inc/jsdialog/jsdialogbuilder.hxx
index 08b16124a7e2..0b0289240bf6 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -28,7 +28,6 @@
 #include <deque>
 #include <list>
 #include <mutex>
-#include <unordered_map>
 
 #define ACTION_TYPE "action_type"
 #define PARENT_ID "parent_id"
@@ -42,7 +41,6 @@ class SvTabListBox;
 class IconView;
 
 typedef std::map<OString, weld::Widget*> WidgetMap;
-typedef std::unordered_map<std::string, OUString> ActionDataMap;
 
 namespace jsdialog
 {
@@ -63,7 +61,7 @@ class JSDialogMessageInfo
 public:
     jsdialog::MessageType m_eType;
     VclPtr<vcl::Window> m_pWindow;
-    std::unique_ptr<ActionDataMap> m_pData;
+    std::unique_ptr<jsdialog::ActionDataMap> m_pData;
 
 private:
     void copy(const JSDialogMessageInfo& rInfo)
@@ -72,14 +70,15 @@ private:
         this->m_pWindow = rInfo.m_pWindow;
         if (rInfo.m_pData)
         {
-            std::unique_ptr<ActionDataMap> pData(new 
ActionDataMap(*rInfo.m_pData));
+            std::unique_ptr<jsdialog::ActionDataMap> pData(
+                new jsdialog::ActionDataMap(*rInfo.m_pData));
             this->m_pData = std::move(pData);
         }
     }
 
 public:
     JSDialogMessageInfo(jsdialog::MessageType eType, VclPtr<vcl::Window> 
pWindow,
-                        std::unique_ptr<ActionDataMap> pData)
+                        std::unique_ptr<jsdialog::ActionDataMap> pData)
         : m_eType(eType)
         , m_pWindow(pWindow)
         , m_pData(std::move(pData))
@@ -120,7 +119,7 @@ public:
     void clearQueue();
     void forceUpdate();
     void sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Window> pWindow,
-                     std::unique_ptr<ActionDataMap> pData = nullptr);
+                     std::unique_ptr<jsdialog::ActionDataMap> pData = nullptr);
 
 private:
     void send(tools::JsonWriter& aJsonWriter);
@@ -128,7 +127,8 @@ private:
     std::unique_ptr<tools::JsonWriter> 
generateWidgetUpdate(VclPtr<vcl::Window> pWindow) const;
     std::unique_ptr<tools::JsonWriter> generateCloseMessage() const;
     std::unique_ptr<tools::JsonWriter>
-    generateActionMessage(VclPtr<vcl::Window> pWindow, 
std::unique_ptr<ActionDataMap> pData) const;
+    generateActionMessage(VclPtr<vcl::Window> pWindow,
+                          std::unique_ptr<jsdialog::ActionDataMap> pData) 
const;
     std::unique_ptr<tools::JsonWriter>
     generatePopupMessage(VclPtr<vcl::Window> pWindow, OUString sParentId, 
OUString sCloseId) const;
     std::unique_ptr<tools::JsonWriter> generateClosePopupMessage(OUString 
sWindowId) const;
@@ -158,7 +158,8 @@ public:
     virtual void sendFullUpdate(bool bForce = false);
     void sendClose();
     void sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce = false);
-    virtual void sendAction(VclPtr<vcl::Window> pWindow, 
std::unique_ptr<ActionDataMap> pData);
+    virtual void sendAction(VclPtr<vcl::Window> pWindow,
+                            std::unique_ptr<jsdialog::ActionDataMap> pData);
     virtual void sendPopup(VclPtr<vcl::Window> pWindow, OUString sParentId, 
OUString sCloseId);
     virtual void sendClosePopup(vcl::LOKWindowId nWindowId);
     void flush() { mpIdleNotify->Invoke(); }
@@ -221,6 +222,9 @@ class JSInstanceBuilder final : public SalInstanceBuilder, 
public JSDialogSender
                                                       const OString& rWidget, 
StringMap& rData);
     friend VCL_DLLPUBLIC void jsdialog::SendFullUpdate(const std::string& 
nWindowId,
                                                        const OString& rWidget);
+    friend VCL_DLLPUBLIC void jsdialog::SendAction(const std::string& 
nWindowId,
+                                                   const OString& rWidget,
+                                                   
std::unique_ptr<jsdialog::ActionDataMap> pData);
 
     static std::map<std::string, WidgetMap>& GetLOKWeldWidgetsMap();
     static void InsertWindowToMap(const std::string& nWindowId);
@@ -317,7 +321,7 @@ public:
 
     virtual void sendFullUpdate(bool bForce = false) = 0;
 
-    virtual void sendAction(std::unique_ptr<ActionDataMap> pData) = 0;
+    virtual void sendAction(std::unique_ptr<jsdialog::ActionDataMap> pData) = 
0;
 
     virtual void sendPopup(vcl::Window* pPopup, OUString sParentId, OUString 
sCloseId) = 0;
 
@@ -358,7 +362,8 @@ public:
         BaseInstanceClass::show();
         if (!bWasVisible)
         {
-            std::unique_ptr<ActionDataMap> pMap = 
std::make_unique<ActionDataMap>();
+            std::unique_ptr<jsdialog::ActionDataMap> pMap
+                = std::make_unique<jsdialog::ActionDataMap>();
             (*pMap)[ACTION_TYPE] = "show";
             sendAction(std::move(pMap));
         }
@@ -370,7 +375,8 @@ public:
         BaseInstanceClass::hide();
         if (bWasVisible)
         {
-            std::unique_ptr<ActionDataMap> pMap = 
std::make_unique<ActionDataMap>();
+            std::unique_ptr<jsdialog::ActionDataMap> pMap
+                = std::make_unique<jsdialog::ActionDataMap>();
             (*pMap)[ACTION_TYPE] = "hide";
             sendAction(std::move(pMap));
         }
@@ -424,7 +430,7 @@ public:
             m_pSender->sendFullUpdate(bForce);
     }
 
-    virtual void sendAction(std::unique_ptr<ActionDataMap> pData) override
+    virtual void sendAction(std::unique_ptr<jsdialog::ActionDataMap> pData) 
override
     {
         if (!m_bIsFreezed && m_pSender && pData)
             m_pSender->sendAction(BaseInstanceClass::m_xWidget, 
std::move(pData));
diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx
index 409c58ff2d49..4a75f2a99f71 100644
--- a/vcl/jsdialog/executor.cxx
+++ b/vcl/jsdialog/executor.cxx
@@ -41,6 +41,14 @@ void SendFullUpdate(const std::string& nWindowId, const 
OString& rWidget)
         pJSWidget->sendFullUpdate();
 }
 
+void SendAction(const std::string& nWindowId, const OString& rWidget,
+                std::unique_ptr<ActionDataMap> pData)
+{
+    weld::Widget* pWidget = JSInstanceBuilder::FindWeldWidgetsMap(nWindowId, 
rWidget);
+    if (auto pJSWidget = dynamic_cast<BaseJSWidget*>(pWidget))
+        pJSWidget->sendAction(std::move(pData));
+}
+
 bool ExecuteAction(const std::string& nWindowId, const OString& rWidget, 
StringMap& rData)
 {
     weld::Widget* pWidget = JSInstanceBuilder::FindWeldWidgetsMap(nWindowId, 
rWidget);
@@ -192,6 +200,40 @@ bool ExecuteAction(const std::string& nWindowId, const 
OString& rWidget, StringM
                     LOKTrigger::trigger_click(*pArea, Point(10, 10));
                     return true;
                 }
+                else if (sAction == "keypress")
+                {
+                    LOKTrigger::trigger_key_press(
+                        *pArea,
+                        KeyEvent(rData["data"].toUInt32(), 
vcl::KeyCode(rData["data"].toUInt32())));
+                    LOKTrigger::trigger_key_release(
+                        *pArea,
+                        KeyEvent(rData["data"].toUInt32(), 
vcl::KeyCode(rData["data"].toUInt32())));
+                    return true;
+                }
+                else if (sAction == "textselection")
+                {
+                    // start;end
+                    int nSeparatorPos = rData["data"].indexOf(';');
+                    if (nSeparatorPos <= 0)
+                        return true;
+
+                    std::u16string_view aStartPos = rData["data"].subView(0, 
nSeparatorPos);
+                    std::u16string_view aEndPos = 
rData["data"].subView(nSeparatorPos + 1);
+
+                    if (aStartPos.empty() || aEndPos.empty())
+                        return true;
+
+                    int nStart = std::atoi(
+                        OUStringToOString(aStartPos.data(), 
RTL_TEXTENCODING_ASCII_US).getStr());
+                    int nEnd = std::atoi(
+                        OUStringToOString(aEndPos.data(), 
RTL_TEXTENCODING_ASCII_US).getStr());
+
+                    Point aPos(nStart, nEnd);
+                    CommandEvent aCEvt(aPos, CommandEventId::CursorPos);
+                    LOKTrigger::command(*pArea, aCEvt);
+
+                    return true;
+                }
             }
         }
         else if (sControlType == "spinfield")
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index f89d0ca0fc13..b1ca111a07f7 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -88,7 +88,7 @@ void JSDialogNotifyIdle::send(tools::JsonWriter& aJsonWriter)
 
 namespace
 {
-OUString extractActionType(const ActionDataMap& rData)
+OUString extractActionType(const jsdialog::ActionDataMap& rData)
 {
     auto it = rData.find(ACTION_TYPE);
     if (it != rData.end())
@@ -98,7 +98,7 @@ OUString extractActionType(const ActionDataMap& rData)
 };
 
 void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, 
VclPtr<vcl::Window> pWindow,
-                                     std::unique_ptr<ActionDataMap> pData)
+                                     std::unique_ptr<jsdialog::ActionDataMap> 
pData)
 {
     std::scoped_lock aGuard(m_aQueueMutex);
 
@@ -172,7 +172,7 @@ std::unique_ptr<tools::JsonWriter> 
JSDialogNotifyIdle::generateCloseMessage() co
 
 std::unique_ptr<tools::JsonWriter>
 JSDialogNotifyIdle::generateActionMessage(VclPtr<vcl::Window> pWindow,
-                                          std::unique_ptr<ActionDataMap> 
pData) const
+                                          
std::unique_ptr<jsdialog::ActionDataMap> pData) const
 {
     std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
 
@@ -270,6 +270,9 @@ void JSDialogNotifyIdle::Invoke()
     {
         jsdialog::MessageType eType = rMessage.m_eType;
 
+        if (m_sTypeOfJSON == "formulabar" && eType != 
jsdialog::MessageType::Action)
+            continue;
+
         switch (eType)
         {
             case jsdialog::MessageType::FullUpdate:
@@ -344,7 +347,8 @@ void JSDialogSender::sendUpdate(VclPtr<vcl::Window> 
pWindow, bool bForce)
     mpIdleNotify->Start();
 }
 
-void JSDialogSender::sendAction(VclPtr<vcl::Window> pWindow, 
std::unique_ptr<ActionDataMap> pData)
+void JSDialogSender::sendAction(VclPtr<vcl::Window> pWindow,
+                                std::unique_ptr<jsdialog::ActionDataMap> pData)
 {
     if (!mpIdleNotify)
         return;
@@ -358,7 +362,7 @@ void JSDialogSender::sendPopup(VclPtr<vcl::Window> pWindow, 
OUString sParentId,
     if (!mpIdleNotify)
         return;
 
-    std::unique_ptr<ActionDataMap> pData = std::make_unique<ActionDataMap>();
+    std::unique_ptr<jsdialog::ActionDataMap> pData = 
std::make_unique<jsdialog::ActionDataMap>();
     (*pData)[PARENT_ID] = sParentId;
     (*pData)[CLOSE_ID] = sCloseId;
     mpIdleNotify->sendMessage(jsdialog::MessageType::Popup, pWindow, 
std::move(pData));
@@ -370,7 +374,7 @@ void JSDialogSender::sendClosePopup(vcl::LOKWindowId 
nWindowId)
     if (!mpIdleNotify)
         return;
 
-    std::unique_ptr<ActionDataMap> pData = std::make_unique<ActionDataMap>();
+    std::unique_ptr<jsdialog::ActionDataMap> pData = 
std::make_unique<jsdialog::ActionDataMap>();
     (*pData)[WINDOW_ID] = OUString::number(nWindowId);
     mpIdleNotify->sendMessage(jsdialog::MessageType::PopupClose, nullptr, 
std::move(pData));
     flush();
@@ -607,7 +611,6 @@ JSInstanceBuilder::JSInstanceBuilder(vcl::Window* pParent, 
const OUString& rUIRo
     }
 
     initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
-    sendFullUpdate();
 }
 
 std::unique_ptr<JSInstanceBuilder> 
JSInstanceBuilder::CreateDialogBuilder(weld::Widget* pParent,
@@ -1666,7 +1669,7 @@ void JSIconView::select(int pos)
 {
     SalInstanceIconView::select(pos);
 
-    std::unique_ptr<ActionDataMap> pMap = std::make_unique<ActionDataMap>();
+    std::unique_ptr<jsdialog::ActionDataMap> pMap = 
std::make_unique<jsdialog::ActionDataMap>();
     (*pMap)[ACTION_TYPE] = "select";
     (*pMap)["position"] = OUString::number(pos);
     sendAction(std::move(pMap));
commit 3dd8b19b814e959d00235df8bc08f9892f45dd87
Author:     Szymon Kłos <[email protected]>
AuthorDate: Tue Apr 26 18:15:22 2022 +0200
Commit:     Szymon Kłos <[email protected]>
CommitDate: Sun May 1 20:18:40 2022 +0200

    lok: Introduce uno commands for formulabar actions
    
    thanks to that we can reach them using LOK as formulabar
    is not fully welded yet
    
    Change-Id: Icc1963ab11c1e6e3c407222d76b2a87fdaffa652
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133496
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Mert Tumer <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133655
    Tested-by: Jenkins
    Reviewed-by: Szymon Kłos <[email protected]>

diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index a02df6204ad5..fcf95122ad35 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -511,6 +511,9 @@ class SvxZoomSliderItem;
 #define SID_NEXT_TABLE_SEL      (SID_KEYFUNC_START + 40)
 #define SID_PREV_TABLE_SEL      (SID_KEYFUNC_START + 41)
 
+#define SID_ACCEPT_FORMULA      (SID_KEYFUNC_START + 42)
+#define SID_START_FORMULA       (SID_KEYFUNC_START + 43)
+
 #define SID_KEYFUNC_END         (SID_KEYFUNC_START + 50)
 
 #define SID_NEW_SLOTS           (SID_KEYFUNC_END)
diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi
index 38eb86cb27b9..d61f9cb863f8 100644
--- a/sc/sdi/cellsh.sdi
+++ b/sc/sdi/cellsh.sdi
@@ -209,6 +209,8 @@ interface CellSelection
     FID_INSERT_NAME                     [ ExecMethod = ExecuteEdit; 
StateMethod = GetState; ]
     FID_USE_NAME                        [ ExecMethod = ExecuteEdit; 
StateMethod = GetState; ]
     SID_CANCEL                          [ ExecMethod = Execute; ]
+    SID_ACCEPT_FORMULA                  [ ExecMethod = Execute; ]
+    SID_START_FORMULA                   [ ExecMethod = Execute; ]
     SID_TOGGLE_REL                      [ ExecMethod = ExecuteEdit; 
StateMethod = GetState; ]
     SID_POPUP_CONDFRMT                  []
     SID_COLUMN_OPERATIONS               [ ExecMethod = ExecuteEdit; 
StateMethod = GetBlockState; ]
diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi
index a84b7da1348b..edf0ebb7134d 100644
--- a/sc/sdi/scalc.sdi
+++ b/sc/sdi/scalc.sdi
@@ -483,6 +483,42 @@ SfxVoidItem Cancel SID_CANCEL
     GroupId = SfxGroupId::Edit;
 ]
 
+SfxVoidItem AcceptFormula SID_ACCEPT_FORMULA
+()
+[
+    AutoUpdate = FALSE,
+    FastCall = FALSE,
+    ReadOnlyDoc = TRUE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+    Asynchron;
+
+    AccelConfig = TRUE,
+    MenuConfig = FALSE,
+    ToolBoxConfig = TRUE,
+    GroupId = SfxGroupId::Edit;
+]
+
+SfxVoidItem StartFormula SID_START_FORMULA
+()
+[
+    AutoUpdate = FALSE,
+    FastCall = FALSE,
+    ReadOnlyDoc = TRUE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+    Asynchron;
+
+    AccelConfig = TRUE,
+    MenuConfig = FALSE,
+    ToolBoxConfig = TRUE,
+    GroupId = SfxGroupId::Edit;
+]
+
 
 SfxVoidItem ChangeChartData SID_CHART_SOURCE
 (SfxStringItem Name SID_CHART_NAME,SfxStringItem Range 
SID_CHART_SOURCE,SfxBoolItem ColHeaders FN_PARAM_1,SfxBoolItem RowHeaders 
FN_PARAM_2)
@@ -6584,6 +6620,7 @@ SfxUInt16Item NumberFormatType SID_NUMBER_TYPE_FORMAT
 
 
 SfxVoidItem AutoSum SID_AUTO_SUM
+(SfxStringItem Function SID_AUTO_SUM)
 [
     AutoUpdate = FALSE,
     FastCall = FALSE,
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index ff717e5acf44..47c8c0fdb770 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -363,55 +363,61 @@ void ScInputWindow::Select()
         mxTextWindow->Invalidate(); // Or else the Selection remains
     }
     else if (curItemId == SID_INPUT_EQUAL)
+    {
+        StartFormula();
+    }
+}
+
+void ScInputWindow::StartFormula()
+{
+    ScModule* pScMod = SC_MOD();
+    mxTextWindow->StartEditEngine();
+    if ( pScMod->IsEditMode() ) // Isn't if e.g. protected
     {
         mxTextWindow->StartEditEngine();
-        if ( pScMod->IsEditMode() ) // Isn't if e.g. protected
-        {
-            mxTextWindow->StartEditEngine();
 
-            sal_Int32 nStartPos = 1;
-            sal_Int32 nEndPos = 1;
+        sal_Int32 nStartPos = 1;
+        sal_Int32 nEndPos = 1;
 
-            ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( 
SfxViewShell::Current()  );
-            if ( pViewSh )
-            {
-                const OUString& rString = mxTextWindow->GetTextString();
-                const sal_Int32 nLen = rString.getLength();
+        ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( 
SfxViewShell::Current()  );
+        if ( pViewSh )
+        {
+            const OUString& rString = mxTextWindow->GetTextString();
+            const sal_Int32 nLen = rString.getLength();
 
-                ScDocument& rDoc = pViewSh->GetViewData().GetDocument();
-                CellType eCellType = rDoc.GetCellType( 
pViewSh->GetViewData().GetCurPos() );
-                switch ( eCellType )
+            ScDocument& rDoc = pViewSh->GetViewData().GetDocument();
+            CellType eCellType = rDoc.GetCellType( 
pViewSh->GetViewData().GetCurPos() );
+            switch ( eCellType )
+            {
+                case CELLTYPE_VALUE:
                 {
-                    case CELLTYPE_VALUE:
-                    {
-                        nEndPos = nLen + 1;
-                        mxTextWindow->SetTextString("=" +  rString);
-                        break;
-                    }
-                    case CELLTYPE_STRING:
-                    case CELLTYPE_EDIT:
-                        nStartPos = 0;
-                        nEndPos = nLen;
-                        break;
-                    case CELLTYPE_FORMULA:
-                        nEndPos = nLen;
-                        break;
-                    default:
-                        mxTextWindow->SetTextString("=");
-                        break;
+                    nEndPos = nLen + 1;
+                    mxTextWindow->SetTextString("=" +  rString);
+                    break;
                 }
+                case CELLTYPE_STRING:
+                case CELLTYPE_EDIT:
+                    nStartPos = 0;
+                    nEndPos = nLen;
+                    break;
+                case CELLTYPE_FORMULA:
+                    nEndPos = nLen;
+                    break;
+                default:
+                    mxTextWindow->SetTextString("=");
+                    break;
             }
+        }
 
-            EditView* pView = mxTextWindow->GetEditView();
-            if (pView)
-            {
-                if (comphelper::LibreOfficeKit::isActive())
-                    TextGrabFocus();
-                pView->SetSelection( ESelection(0, nStartPos, 0, nEndPos) );
-                pScMod->InputChanged(pView);
-                SetOkCancelMode();
-                pView->SetEditEngineUpdateLayout(true);
-            }
+        EditView* pView = mxTextWindow->GetEditView();
+        if (pView)
+        {
+            if (comphelper::LibreOfficeKit::isActive())
+                TextGrabFocus();
+            pView->SetSelection( ESelection(0, nStartPos, 0, nEndPos) );
+            pScMod->InputChanged(pView);
+            SetOkCancelMode();
+            pView->SetEditEngineUpdateLayout(true);
         }
     }
 }
@@ -1014,6 +1020,7 @@ IMPL_LINK_NOARG(ScInputWindow, DropdownClickHdl, ToolBox 
*, void)
 {
     ToolBoxItemId nCurID = GetCurItemId();
     EndSelection();
+
     if (nCurID == SID_INPUT_SUM)
     {
         tools::Rectangle aRect(GetItemRect(SID_INPUT_SUM));
diff --git a/sc/source/ui/inc/inputwin.hxx b/sc/source/ui/inc/inputwin.hxx
index 507d91ce5c4a..6bd4c3152712 100644
--- a/sc/source/ui/inc/inputwin.hxx
+++ b/sc/source/ui/inc/inputwin.hxx
@@ -301,6 +301,7 @@ public:
     void            SetSumAssignMode();
     void            EnableButtons( bool bEnable );
 
+    void            StartFormula();
     void            SetFormulaMode( bool bSet );
 
     bool            IsInputActive();
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index ca337a557cd1..9234191e008c 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -2817,9 +2817,24 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
 
         case SID_AUTO_SUM:
             {
+                const SfxItemSet *pArgs = rReq.GetArgs();
+                const OUString sFunction = pArgs ?
+                    static_cast<const SfxStringItem&>( pArgs->Get( 
SID_AUTO_SUM ) ).GetValue()
+                    : "";
+
+                OpCode eFunction = ocSum;
+                if (sFunction == "average")
+                    eFunction = ocAverage;
+                else if (sFunction == "count")
+                    eFunction = ocCount;
+                else if (sFunction == "min")
+                    eFunction = ocMin;
+                if (sFunction == "max")
+                    eFunction = ocMax;
+
                 bool bSubTotal = false;
                 bool bRangeFinder = false;
-                const OUString aFormula = pTabViewShell->DoAutoSum( 
bRangeFinder, bSubTotal , ocSum );
+                const OUString aFormula = pTabViewShell->DoAutoSum( 
bRangeFinder, bSubTotal , eFunction );
                 if ( !aFormula.isEmpty() )
                 {
                     const sal_Int32 nPar = aFormula.indexOf( '(' );
diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx
index 57299cdaa45b..6a23b5ab9e43 100644
--- a/sc/source/ui/view/cellsh3.cxx
+++ b/sc/source/ui/view/cellsh3.cxx
@@ -47,6 +47,8 @@
 #include <columnspanset.hxx>
 #include <comphelper/lok.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <inputhdl.hxx>
+#include <inputwin.hxx>
 
 #include <memory>
 
@@ -1014,6 +1016,21 @@ void ScCellShell::Execute( SfxRequest& rReq )
             }
             break;
 
+        case SID_ACCEPT_FORMULA:
+            {
+                if (GetViewData().HasEditView(GetViewData().GetActivePart()))
+                    pScMod->InputEnterHandler();
+            }
+            break;
+
+        case SID_START_FORMULA:
+            {
+                ScInputHandler* pInputHandler = pScMod->GetInputHdl();
+                if (pInputHandler && pInputHandler->GetInputWindow())
+                    pInputHandler->GetInputWindow()->StartFormula();
+            }
+            break;
+
         case SID_DATA_SELECT:
             pTabViewShell->StartDataSelect();
             break;

Reply via email to