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/+/188221
Tested-by: Jenkins
Reviewed-by: Sahil Gautam <sahil.gautam@collabora.com>
Reviewed-by: Samuel Mehrbrodt <samuel.mehrbrodt@collabora.com>
This commit is contained in:
Sahil Gautam
2025-07-29 00:07:10 +02:00
parent e9abbdd178
commit 6ece875046
6 changed files with 147 additions and 74 deletions
@@ -2184,6 +2184,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>
+1 -1
View File
@@ -3217,7 +3217,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,
+13 -71
View File
@@ -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)
@@ -405,27 +409,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)
@@ -433,63 +421,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();
+4 -1
View File
@@ -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;
@@ -70,6 +72,7 @@ private:
void UpdateFavouritesList();
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 );
@@ -82,7 +85,7 @@ private:
DECL_LINK( KeyInputHdl, const KeyEvent&, bool);
public:
ScFunctionWin(weld::Widget* pParent);
ScFunctionWin(weld::Widget* pParent, SfxBindings* pBindings);
virtual ~ScFunctionWin() override;
+1 -1
View File
@@ -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;
}
+120
View File
@@ -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>
@@ -53,6 +55,7 @@
#include <cellsh.hxx>
#include <ftools.hxx>
#include <funcdesc.hxx>
#include <sc.hrc>
#include <document.hxx>
#include <patattr.hxx>
@@ -2094,6 +2097,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