1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/string.hxx>
21 #include <editeng/editview.hxx>
22 #include <sfx2/viewsh.hxx>
23 #include <formula/funcvarargs.h>
27 #include <inputhdl.hxx>
28 #include <tabvwsh.hxx>
29 #include <funcdesc.hxx>
31 #include <dwfunctr.hxx>
33 /*************************************************************************
34 #* Member: ScFunctionWin
35 #*------------------------------------------------------------------------
37 #* Class: ScFunctionWin
39 #* Function: Constructor of ScFunctionWin Class
41 #* Input: Sfx - links, window, resource
45 #************************************************************************/
47 ScFunctionWin::ScFunctionWin(vcl::Window
* pParent
, const css::uno::Reference
<css::frame::XFrame
> &rFrame
)
48 : PanelLayout(pParent
, "FunctionPanel", "modules/scalc/ui/functionpanel.ui", rFrame
)
49 , xCatBox(m_xBuilder
->weld_combo_box("category"))
50 , xFuncList(m_xBuilder
->weld_tree_view("funclist"))
51 , xInsertButton(m_xBuilder
->weld_button("insert"))
52 , xFiFuncDesc(m_xBuilder
->weld_label("funcdesc"))
53 , xConfigListener(new comphelper::ConfigurationListener("/org.openoffice.Office.Calc/Formula/Syntax"))
54 , xConfigChange(std::make_unique
<EnglishFunctionNameChange
>(xConfigListener
, this))
57 xFuncList
->set_size_request(-1, xFuncList
->get_height_rows(10));
62 xFiFuncDesc
->set_size_request(-1, 5 * xFiFuncDesc
->get_text_height());
64 xCatBox
->connect_changed(LINK( this, ScFunctionWin
, SelComboHdl
));
65 xFuncList
->connect_changed(LINK( this, ScFunctionWin
, SelTreeHdl
));
67 xFuncList
->connect_row_activated(LINK( this, ScFunctionWin
, SetRowActivatedHdl
));
68 xInsertButton
->connect_clicked(LINK( this, ScFunctionWin
, SetSelectionClickHdl
));
70 xCatBox
->set_active(0);
72 SelComboHdl(*xCatBox
);
74 m_pInitialFocusWidget
= xCatBox
.get();
77 /*************************************************************************
78 #* Member: ScFunctionWin
79 #*------------------------------------------------------------------------
81 #* Class: ScFunctionWin
83 #* Function: Destructor of ScFunctionWin Class
89 #************************************************************************/
91 ScFunctionWin::~ScFunctionWin()
96 void ScFunctionWin::dispose()
100 xConfigChange
.reset();
101 xConfigListener
->dispose();
102 xConfigListener
.clear();
106 xInsertButton
.reset();
108 PanelLayout::dispose();
111 /*************************************************************************
112 #* Member: UpdateFunctionList
113 #*------------------------------------------------------------------------
115 #* Class: ScFunctionWin
117 #* Function: Updates the list of functions depending on the set category
123 #************************************************************************/
125 void ScFunctionWin::InitLRUList()
127 ScFunctionMgr
* pFuncMgr
= ScGlobal::GetStarCalcFunctionMgr();
128 pFuncMgr
->fillLastRecentlyUsedFunctions(aLRUList
);
130 sal_Int32 nSelPos
= xCatBox
->get_active();
133 UpdateFunctionList();
136 /*************************************************************************
137 #* Member: UpdateFunctionList
138 #*------------------------------------------------------------------------
140 #* Class: ScFunctionWin
142 #* Function: Updates the list of last used functions.
148 #************************************************************************/
150 void ScFunctionWin::UpdateLRUList()
152 if (pFuncDesc
&& pFuncDesc
->nFIndex
!=0)
154 ScModule
* pScMod
= SC_MOD();
155 pScMod
->InsertEntryToLRUList(pFuncDesc
->nFIndex
);
159 /*************************************************************************
160 #* Member: SetDescription
161 #*------------------------------------------------------------------------
163 #* Class: ScFunctionWin
171 #************************************************************************/
173 void ScFunctionWin::SetDescription()
175 xFiFuncDesc
->set_label(EMPTY_OUSTRING
);
176 const ScFuncDesc
* pDesc
=
177 reinterpret_cast<const ScFuncDesc
*>(xFuncList
->get_selected_id().toInt64());
180 pDesc
->initArgumentInfo(); // full argument info is needed
182 OUStringBuffer
aBuf(xFuncList
->get_selected_text());
183 aBuf
.append(":\n\n");
184 aBuf
.append(pDesc
->GetParamList());
186 aBuf
.append(*pDesc
->mxFuncDesc
);
188 xFiFuncDesc
->set_label(aBuf
.makeStringAndClear());
192 /*************************************************************************
193 #* Member: UpdateFunctionList
194 #*------------------------------------------------------------------------
196 #* Class: ScFunctionWin
198 #* Function: Updates the list of functions depending on the set category
204 #************************************************************************/
206 void ScFunctionWin::UpdateFunctionList()
208 sal_Int32 nSelPos
= xCatBox
->get_active();
209 sal_Int32 nCategory
= ( -1 != nSelPos
)
217 ScFunctionMgr
* pFuncMgr
= ScGlobal::GetStarCalcFunctionMgr();
219 const ScFuncDesc
* pDesc
= pFuncMgr
->First( nCategory
);
222 xFuncList
->append(OUString::number(reinterpret_cast<sal_Int64
>(pDesc
)), *(pDesc
->mxFuncName
));
223 pDesc
= pFuncMgr
->Next();
228 for (const formula::IFunctionDescription
* pDesc
: aLRUList
)
232 xFuncList
->append(OUString::number(reinterpret_cast<sal_Int64
>(pDesc
)), pDesc
->getFunctionName());
239 if (xFuncList
->n_children() > 0)
241 xFuncList
->set_sensitive(true);
242 xFuncList
->select(0);
246 xFuncList
->set_sensitive(false);
250 /*************************************************************************
252 #*------------------------------------------------------------------------
254 #* Class: ScFunctionWin
256 #* Function: Save input into document. Is called after clicking the
257 #* Apply button or a double-click on the function list.
263 #************************************************************************/
265 void ScFunctionWin::DoEnter()
267 OUStringBuffer aArgStr
;
268 OUString aString
=xFuncList
->get_selected_text();
269 SfxViewShell
* pCurSh
= SfxViewShell::Current();
272 if(!aString
.isEmpty())
274 OUString aFirstArgStr
;
275 ScModule
* pScMod
= SC_MOD();
276 ScTabViewShell
* pViewSh
= dynamic_cast<ScTabViewShell
*>( pCurSh
);
277 ScInputHandler
* pHdl
= pScMod
->GetInputHdl( pViewSh
);
278 if(!pScMod
->IsEditMode())
280 pScMod
->SetInputMode(SC_INPUT_TABLE
);
281 // the above call can result in us being disposed
282 if (OutputDevice::isDisposed())
284 aString
= "=" + xFuncList
->get_selected_text();
288 const ScFuncDesc
* pDesc
=
289 reinterpret_cast<const ScFuncDesc
*>(xFuncList
->get_selected_id().toInt64());
294 nArgs
= pDesc
->nArgCount
;
297 // NOTE: Theoretically the first parameter could have the
298 // suppress flag as well, but practically it doesn't.
299 aFirstArgStr
= pDesc
->maDefArgNames
[0];
300 aFirstArgStr
= comphelper::string::strip(aFirstArgStr
, ' ');
301 aFirstArgStr
= aFirstArgStr
.replaceAll(" ", "_");
302 aArgStr
= aFirstArgStr
;
303 if ( nArgs
!= VAR_ARGS
&& nArgs
!= PAIRED_VAR_ARGS
)
304 { // no VarArgs or Fix plus VarArgs, but not VarArgs only
306 if (nArgs
>= PAIRED_VAR_ARGS
)
307 nFix
= nArgs
- PAIRED_VAR_ARGS
+ 2;
308 else if (nArgs
>= VAR_ARGS
)
309 nFix
= nArgs
- VAR_ARGS
+ 1;
312 for ( sal_uInt16 nArg
= 1;
313 nArg
< nFix
&& !pDesc
->pDefArgFlags
[nArg
].bOptional
; nArg
++ )
315 aArgStr
.append("; ");
316 OUString sTmp
= pDesc
->maDefArgNames
[nArg
];
317 sTmp
= comphelper::string::strip(sTmp
, ' ');
318 sTmp
= sTmp
.replaceAll(" ", "_");
319 aArgStr
.append(sTmp
);
326 if (pHdl
->GetEditString().isEmpty())
328 aString
= "=" + xFuncList
->get_selected_text();
330 EditView
*pEdView
=pHdl
->GetActiveView();
331 if(pEdView
!=nullptr) // @ needed because of crash during setting a name
335 pHdl
->InsertFunction(aString
);
336 pEdView
->InsertText(aArgStr
.makeStringAndClear(),true);
337 ESelection aESel
=pEdView
->GetSelection();
338 aESel
.nEndPos
= aESel
.nStartPos
+ aFirstArgStr
.getLength();
339 pEdView
->SetSelection(aESel
);
345 pEdView
->InsertText(aString
);
354 vcl::Window
* pShellWnd
= pCurSh
->GetWindow();
357 pShellWnd
->GrabFocus();
362 /*************************************************************************
364 #*------------------------------------------------------------------------
366 #* Class: ScFunctionWin
368 #* Function: A change of the category will update the list of functions.
374 #************************************************************************/
376 IMPL_LINK_NOARG(ScFunctionWin
, SelComboHdl
, weld::ComboBox
&, void)
378 UpdateFunctionList();
382 IMPL_LINK_NOARG(ScFunctionWin
, SelTreeHdl
, weld::TreeView
&, void)
387 /*************************************************************************
389 #*------------------------------------------------------------------------
391 #* Class: ScFunctionWin
393 #* Function: A change of the category will update the list of functions.
399 #************************************************************************/
401 IMPL_LINK_NOARG( ScFunctionWin
, SetSelectionClickHdl
, weld::Button
&, void )
403 DoEnter(); // saves the input
406 IMPL_LINK_NOARG( ScFunctionWin
, SetRowActivatedHdl
, weld::TreeView
&, bool )
408 DoEnter(); // saves the input
412 void EnglishFunctionNameChange::setProperty(const css::uno::Any
&rProperty
)
414 ConfigurationListenerProperty::setProperty(rProperty
);
415 m_xFunctionWin
->InitLRUList();
416 m_xFunctionWin
->UpdateFunctionList();
419 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */