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