officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu |    8 
 sc/sdi/scalc.sdi                                                  |    2 
 sc/source/ui/formdlg/dwfunctr.cxx                                 |   84 
+------
 sc/source/ui/inc/dwfunctr.hxx                                     |    5 
 sc/source/ui/sidebar/ScPanelFactory.cxx                           |    2 
 sc/source/ui/view/cellsh1.cxx                                     |  120 
++++++++++
 6 files changed, 147 insertions(+), 74 deletions(-)

New commits:
commit 9a423f676afdb94de5b3a249d18fa921e13a5360
Author:     Sahil Gautam <sahil.gau...@collabora.com>
AuthorDate: Fri Jul 18 02:52:40 2025 +0530
Commit:     Sahil Gautam <sahil.gau...@collabora.com>
CommitDate: Tue Jul 29 00:07:31 2025 +0200

    calc: add parameters to .uno:InsertFunction
    
    + move the formula insertion logic from sidebar to the uno command
    + use the unoCommand with parameters in the sidebar code
    
    Change-Id: Ib211b9829e39bdd6dcc6d0e1f2afac6671fa1c8c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188023
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Sahil Gautam <sahil.gau...@collabora.com>

diff --git a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
index cb39c8c5a20b..83c4ee8f1fc1 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
@@ -2187,6 +2187,14 @@
           <value>1</value>
         </prop>
       </node>
+      <node oor:name=".uno:InsertFunction" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Insert Function</value>
+        </prop>
+        <prop oor:name="Properties" oor:type="xs:int">
+          <value>1</value>
+        </prop>
+      </node>
       <node oor:name=".uno:TableSelectAll" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">Select All Sheets</value>
diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi
index 20012f564304..bfffd7800b7c 100644
--- a/sc/sdi/scalc.sdi
+++ b/sc/sdi/scalc.sdi
@@ -3200,7 +3200,7 @@ SfxVoidItem InsertFile FID_INSERT_FILE
 
 
 SfxVoidItem InsertFunction SID_INS_FUNCTION
-()
+(SfxStringItem FunctionName FN_PARAM_1,SfxInt16Item FunctionCategory 
FN_PARAM_2,SfxStringItem FunctionId FN_PARAM_3)
 [
     AutoUpdate = FALSE,
     FastCall = FALSE,
diff --git a/sc/source/ui/formdlg/dwfunctr.cxx 
b/sc/source/ui/formdlg/dwfunctr.cxx
index 46baa84adf69..cc179683e222 100644
--- a/sc/source/ui/formdlg/dwfunctr.cxx
+++ b/sc/source/ui/formdlg/dwfunctr.cxx
@@ -17,6 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <basctl/basctldllpublic.hxx>
 #include <comphelper/string.hxx>
 #include <editeng/editview.hxx>
 #include <sfx2/viewsh.hxx>
@@ -28,6 +29,8 @@
 
 #include <global.hxx>
 #include <scmod.hxx>
+#include <sc.hrc>
+#include <svl/stritem.hxx>
 #include <inputhdl.hxx>
 #include <tabvwsh.hxx>
 #include <funcdesc.hxx>
@@ -49,7 +52,7 @@
 #*
 #************************************************************************/
 
-ScFunctionWin::ScFunctionWin(weld::Widget* pParent)
+ScFunctionWin::ScFunctionWin(weld::Widget* pParent, SfxBindings* pBindings)
     : PanelLayout(pParent, u"FunctionPanel"_ustr, 
u"modules/scalc/ui/functionpanel.ui"_ustr)
     , xCatBox(m_xBuilder->weld_combo_box(u"category"_ustr))
     , xFuncList(m_xBuilder->weld_tree_view(u"funclist"_ustr))
@@ -59,6 +62,7 @@ ScFunctionWin::ScFunctionWin(weld::Widget* pParent)
     , 
xSimilaritySearch(m_xBuilder->weld_check_button(u"similaritysearch"_ustr))
     , xFiFuncDesc(m_xBuilder->weld_text_view(u"funcdesc"_ustr))
     , m_xSearchString(m_xBuilder->weld_entry(u"search"_ustr))
+    , m_pBindings(pBindings)
     , xConfigListener(new 
comphelper::ConfigurationListener(u"/org.openoffice.Office.Calc/Formula/Syntax"_ustr))
     , 
xConfigChange(std::make_unique<EnglishFunctionNameChange>(xConfigListener, 
this))
     , pFuncDesc(nullptr)
@@ -380,27 +384,11 @@ void ScFunctionWin::DoEnter(bool bDoubleOrEnter)
         return;
     }
 
-    OUStringBuffer aArgStr;
     SfxViewShell* pCurSh = SfxViewShell::Current();
     nArgs=0;
 
     if(!aString.isEmpty())
     {
-        OUString aFirstArgStr;
-        ScModule* pScMod = ScModule::get();
-        ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( pCurSh );
-        ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
-        if(!pScMod->IsEditMode())
-        {
-            rtl::Reference<comphelper::ConfigurationListener> 
xDetectDisposed(xConfigListener);
-            pScMod->SetInputMode(SC_INPUT_TABLE);
-            // the above call can result in us being disposed
-            if (xDetectDisposed->isDisposed())
-                return;
-            aString = "=" + xFuncList->get_selected_text();
-            if (pHdl)
-                pHdl->ClearText();
-        }
         const ScFuncDesc* pDesc =
              weld::fromId<const ScFuncDesc*>(xFuncList->get_selected_id());
         if (pDesc)
@@ -408,63 +396,17 @@ void ScFunctionWin::DoEnter(bool bDoubleOrEnter)
             pFuncDesc=pDesc;
             UpdateLRUList();
             nArgs = pDesc->nArgCount;
-            if(nArgs>0)
-            {
-                // NOTE: Theoretically the first parameter could have the
-                // suppress flag as well, but practically it doesn't.
-                aFirstArgStr = pDesc->maDefArgNames[0];
-                aFirstArgStr = comphelper::string::strip(aFirstArgStr, ' ');
-                aFirstArgStr = aFirstArgStr.replaceAll(" ", "_");
-                aArgStr = aFirstArgStr;
-                if ( nArgs != VAR_ARGS && nArgs != PAIRED_VAR_ARGS )
-                {   // no VarArgs or Fix plus VarArgs, but not VarArgs only
-                    sal_uInt16 nFix;
-                    if (nArgs >= PAIRED_VAR_ARGS)
-                        nFix = nArgs - PAIRED_VAR_ARGS + 2;
-                    else if (nArgs >= VAR_ARGS)
-                        nFix = nArgs - VAR_ARGS + 1;
-                    else
-                        nFix = nArgs;
-                    for ( sal_uInt16 nArg = 1;
-                            nArg < nFix && 
!pDesc->pDefArgFlags[nArg].bOptional; nArg++ )
-                    {
-                        aArgStr.append("; ");
-                        OUString sTmp = pDesc->maDefArgNames[nArg];
-                        sTmp = comphelper::string::strip(sTmp, ' ');
-                        sTmp = sTmp.replaceAll(" ", "_");
-                        aArgStr.append(sTmp);
-                    }
-                }
-            }
-        }
-        if (pHdl)
-        {
-            if (pHdl->GetEditString().isEmpty())
-            {
-                aString = "=" + xFuncList->get_selected_text();
-            }
-            EditView *pEdView=pHdl->GetActiveView();
-            if(pEdView!=nullptr) // @ needed because of crash during setting a 
name
-            {
-                if(nArgs>0)
-                {
-                    pHdl->InsertFunction(aString);
-                    pEdView->InsertText(aArgStr.makeStringAndClear(),true);
-                    ESelection  aESel=pEdView->GetSelection();
-                    aESel.end.nIndex = aESel.start.nIndex + 
aFirstArgStr.getLength();
-                    pEdView->SetSelection(aESel);
-                    pHdl->DataChanged();
-                }
-                else
-                {
-                    aString += "()";
-                    pEdView->InsertText(aString);
-                    pHdl->DataChanged();
-                }
-            }
         }
         InitLRUList();
     }
+
+    const SfxStringItem aFunction(FN_PARAM_1, aString);
+    // -1 when function-id is available, category index otherwise
+    const SfxInt16Item nCategory(FN_PARAM_2, -1);
+    const SfxStringItem aFunctionId(FN_PARAM_3, xFuncList->get_selected_id());
+    GetBindings().GetDispatcher()->ExecuteList(SID_INS_FUNCTION, 
SfxCallMode::SYNCHRON,
+                                               { &aFunction, &nCategory, 
&aFunctionId });
+
     if ( pCurSh )
     {
         vcl::Window* pShellWnd = pCurSh->GetWindow();
diff --git a/sc/source/ui/inc/dwfunctr.hxx b/sc/source/ui/inc/dwfunctr.hxx
index 9c05491dac2d..5808ed2e3a08 100644
--- a/sc/source/ui/inc/dwfunctr.hxx
+++ b/sc/source/ui/inc/dwfunctr.hxx
@@ -21,6 +21,7 @@
 #include <comphelper/configurationlistener.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
 #include <unordered_map>
+#include <sfx2/bindings.hxx>
 
 class ScFuncDesc;
 namespace formula { class IFunctionDescription; }
@@ -52,6 +53,7 @@ private:
     std::unique_ptr<weld::CheckButton> xSimilaritySearch;
     std::unique_ptr<weld::TextView> xFiFuncDesc;
     std::unique_ptr<weld::Entry> m_xSearchString;
+    SfxBindings* m_pBindings;
 
     rtl::Reference<comphelper::ConfigurationListener> xConfigListener;
     std::unique_ptr<EnglishFunctionNameChange> xConfigChange;
@@ -68,6 +70,7 @@ private:
     void            UpdateLRUList();
     void            DoEnter(bool bDouble_or_Enter = false);
     void            SetDescription();
+    SfxBindings&    GetBindings() const { return *m_pBindings; }
     weld::TreeIter* FillCategoriesMap(const OUString&, bool);
 
                     DECL_LINK( SetRowActivatedHdl, weld::TreeView&, bool );
@@ -80,7 +83,7 @@ private:
                     DECL_LINK( KeyInputHdl, const KeyEvent&, bool);
 
 public:
-    ScFunctionWin(weld::Widget* pParent);
+    ScFunctionWin(weld::Widget* pParent, SfxBindings* pBindings);
 
     virtual ~ScFunctionWin() override;
 
diff --git a/sc/source/ui/sidebar/ScPanelFactory.cxx 
b/sc/source/ui/sidebar/ScPanelFactory.cxx
index 833f2187df90..37df0fc263ab 100644
--- a/sc/source/ui/sidebar/ScPanelFactory.cxx
+++ b/sc/source/ui/sidebar/ScPanelFactory.cxx
@@ -91,7 +91,7 @@ Reference<ui::XUIElement> SAL_CALL 
ScPanelFactory::createUIElement (
         }
         else if (rsResourceURL.endsWith("/FunctionsPanel"))
         {
-            xPanel = std::make_unique<ScFunctionWin>(pParent);
+            xPanel = std::make_unique<ScFunctionWin>(pParent, pBindings);
             nMinimumSize = 0;
         }
 
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 763cdf07a8ef..2323f26d1696 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -29,6 +29,8 @@
 #include <comphelper/lok.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/propertysequence.hxx>
+#include <comphelper/string.hxx>
+#include <formula/funcvarargs.h>
 #include <svl/stritem.hxx>
 #include <svl/numformat.hxx>
 #include <svl/zforlist.hxx>
@@ -52,6 +54,7 @@
 
 #include <cellsh.hxx>
 #include <ftools.hxx>
+#include <funcdesc.hxx>
 #include <sc.hrc>
 #include <document.hxx>
 #include <patattr.hxx>
@@ -2134,6 +2137,123 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
 
         case SID_INS_FUNCTION:
             {
+                const SfxPoolItem* pFunction;
+                const SfxPoolItem* pCategory;
+                const SfxPoolItem* pFunctionId;
+                OUString aFunction;
+                sal_Int16 nCategory = -1;
+                OUString aFunctionId;
+
+                bool bFuncHasCategoryOrId = false;
+                if (pReqArgs && pReqArgs->HasItem(FN_PARAM_1, &pFunction)
+                    && pReqArgs->HasItem(FN_PARAM_2, &pCategory)) // -1 when 
aFunctionId not empty
+                {
+                    aFunction = static_cast<const 
SfxStringItem*>(pFunction)->GetValue();
+                    nCategory = static_cast<const 
SfxInt16Item*>(pCategory)->GetValue();
+
+                    if (nCategory == -1 && pReqArgs->HasItem(FN_PARAM_3, 
&pFunctionId))
+                        aFunctionId = static_cast<const 
SfxStringItem*>(pFunctionId)->GetValue();
+
+                    bFuncHasCategoryOrId = nCategory != -1 || 
!aFunctionId.isEmpty();
+                }
+
+                if (bFuncHasCategoryOrId)
+                {
+                    ScInputHandler* pHdl = pScMod->GetInputHdl(pTabViewShell);
+                    OUString aString = aFunction;
+                    if (!pScMod->IsEditMode())
+                    {
+                        pScMod->SetInputMode(SC_INPUT_TABLE);
+                        aString = "=" + aFunction;
+                        if (pHdl)
+                            pHdl->ClearText();
+                    }
+
+                    const ScFuncDesc* pDesc;
+                    if (nCategory == -1)
+                        pDesc = weld::fromId<const ScFuncDesc*>(aFunctionId);
+                    else
+                    {
+                        ScFunctionMgr* pFuncMgr = 
ScGlobal::GetStarCalcFunctionMgr();
+                        const CharClass* pCharClass
+                            = 
(ScGlobal::GetStarCalcFunctionList()->IsEnglishFunctionNames()
+                                   ? ScCompiler::GetCharClassEnglish()
+                                   : ScCompiler::GetCharClassLocalized());
+
+                        pDesc = pFuncMgr->First(nCategory);
+                        while (
+                            pDesc
+                            && 
!pCharClass->uppercase(pDesc->getFunctionName()).equals(aFunction))
+                        {
+                            pDesc = pFuncMgr->Next();
+                        }
+                    }
+                    if (!pDesc)
+                    {
+                        rReq.Ignore();
+                        break;
+                    }
+
+                    OUStringBuffer aArgStr;
+                    OUString aFirstArgStr;
+                    sal_uInt16 nArgs = pDesc->nArgCount;
+                    if (nArgs > 0)
+                    {
+                        // NOTE: Theoretically the first parameter could have 
the
+                        // suppress flag as well, but practically it doesn't.
+                        aFirstArgStr = pDesc->maDefArgNames[0];
+                        aFirstArgStr = comphelper::string::strip(aFirstArgStr, 
' ');
+                        aFirstArgStr = aFirstArgStr.replaceAll(" ", "_");
+                        aArgStr = aFirstArgStr;
+                        if (nArgs != VAR_ARGS && nArgs != PAIRED_VAR_ARGS)
+                        { // no VarArgs or Fix plus VarArgs, but not VarArgs 
only
+                            sal_uInt16 nFix;
+                            if (nArgs >= PAIRED_VAR_ARGS)
+                                nFix = nArgs - PAIRED_VAR_ARGS + 2;
+                            else if (nArgs >= VAR_ARGS)
+                                nFix = nArgs - VAR_ARGS + 1;
+                            else
+                                nFix = nArgs;
+                            for (sal_uInt16 nArg = 1;
+                                 nArg < nFix && 
!pDesc->pDefArgFlags[nArg].bOptional; nArg++)
+                            {
+                                aArgStr.append("; ");
+                                OUString sTmp = pDesc->maDefArgNames[nArg];
+                                sTmp = comphelper::string::strip(sTmp, ' ');
+                                sTmp = sTmp.replaceAll(" ", "_");
+                                aArgStr.append(sTmp);
+                            }
+                        }
+                    }
+
+                    if (pHdl)
+                    {
+                        if (pHdl->GetEditString().isEmpty())
+                            aString = "=" + aFunction;
+                        EditView* pEdView = pHdl->GetActiveView();
+                        if (pEdView != nullptr)
+                        {
+                            if (nArgs > 0)
+                            {
+                                pHdl->InsertFunction(aString);
+                                
pEdView->InsertText(aArgStr.makeStringAndClear(), true);
+                                ESelection aESel = pEdView->GetSelection();
+                                aESel.end.nIndex = aESel.start.nIndex + 
aFirstArgStr.getLength();
+                                pEdView->SetSelection(aESel);
+                                pHdl->DataChanged();
+                            }
+                            else
+                            {
+                                aString += "()";
+                                pEdView->InsertText(aString);
+                                pHdl->DataChanged();
+                            }
+                        }
+                    }
+                    rReq.Ignore();
+                    break;
+                }
+
                 const SfxBoolItem* pOkItem = static_cast<const 
SfxBoolItem*>(&pReqArgs->Get( SID_DLG_RETOK ));
 
                 if ( pOkItem->GetValue() )      // OK

Reply via email to