LibreOffice Module sc (master)  1
dwfunctr.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <comphelper/string.hxx>
21 #include <editeng/editview.hxx>
22 #include <sfx2/viewsh.hxx>
23 #include <formula/funcvarargs.h>
24 
25 #include <global.hxx>
26 #include <scmod.hxx>
27 #include <inputhdl.hxx>
28 #include <tabvwsh.hxx>
29 #include <funcdesc.hxx>
30 
31 #include <dwfunctr.hxx>
32 
33 /*************************************************************************
34 #* Member: ScFunctionWin
35 #*------------------------------------------------------------------------
36 #*
37 #* Class: ScFunctionWin
38 #*
39 #* Function: Constructor of ScFunctionWin Class
40 #*
41 #* Input: Sfx - links, window, resource
42 #*
43 #* Output: ---
44 #*
45 #************************************************************************/
46 
48  : PanelLayout(pParent, "FunctionPanel", "modules/scalc/ui/functionpanel.ui")
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))
55  , pFuncDesc(nullptr)
56 {
57  xFuncList->set_size_request(-1, xFuncList->get_height_rows(10));
58 
59  InitLRUList();
60 
61  nArgs=0;
62  xFiFuncDesc->set_size_request(-1, 5 * xFiFuncDesc->get_text_height());
63 
64  xCatBox->connect_changed(LINK( this, ScFunctionWin, SelComboHdl));
65  xFuncList->connect_changed(LINK( this, ScFunctionWin, SelTreeHdl));
66 
67  xFuncList->connect_row_activated(LINK( this, ScFunctionWin, SetRowActivatedHdl));
68  xInsertButton->connect_clicked(LINK( this, ScFunctionWin, SetSelectionClickHdl));
69 
70  xCatBox->set_active(0);
71 
72  SelComboHdl(*xCatBox);
73 }
74 
75 /*************************************************************************
76 #* Member: ScFunctionWin
77 #*------------------------------------------------------------------------
78 #*
79 #* Class: ScFunctionWin
80 #*
81 #* Function: Destructor of ScFunctionWin Class
82 #*
83 #* Input: ---
84 #*
85 #* Output: ---
86 #*
87 #************************************************************************/
88 
90 {
91  xConfigChange.reset();
92  xConfigListener->dispose();
93  xConfigListener.clear();
94 
95  xCatBox.reset();
96  xFuncList.reset();
97  xInsertButton.reset();
98  xFiFuncDesc.reset();
99 }
100 
101 /*************************************************************************
102 #* Member: UpdateFunctionList
103 #*------------------------------------------------------------------------
104 #*
105 #* Class: ScFunctionWin
106 #*
107 #* Function: Updates the list of functions depending on the set category
108 #*
109 #* Input: ---
110 #*
111 #* Output: ---
112 #*
113 #************************************************************************/
114 
116 {
119 
120  sal_Int32 nSelPos = xCatBox->get_active();
121 
122  if (nSelPos == 0)
124 }
125 
126 /*************************************************************************
127 #* Member: UpdateFunctionList
128 #*------------------------------------------------------------------------
129 #*
130 #* Class: ScFunctionWin
131 #*
132 #* Function: Updates the list of last used functions.
133 #*
134 #* Input: ---
135 #*
136 #* Output: ---
137 #*
138 #************************************************************************/
139 
141 {
142  if (pFuncDesc && pFuncDesc->nFIndex!=0)
143  {
144  ScModule* pScMod = SC_MOD();
146  }
147 }
148 
149 /*************************************************************************
150 #* Member: SetDescription
151 #*------------------------------------------------------------------------
152 #*
153 #* Class: ScFunctionWin
154 #*
155 #* Function:
156 #*
157 #* Input: ---
158 #*
159 #* Output: ---
160 #*
161 #************************************************************************/
162 
164 {
165  xFiFuncDesc->set_label(EMPTY_OUSTRING);
166  const ScFuncDesc* pDesc =
167  reinterpret_cast<const ScFuncDesc*>(xFuncList->get_selected_id().toInt64());
168  if (pDesc)
169  {
170  pDesc->initArgumentInfo(); // full argument info is needed
171 
172  OUString aBuf = xFuncList->get_selected_text() +
173  ":\n\n" +
174  pDesc->GetParamList() +
175  "\n\n" +
176  *pDesc->mxFuncDesc;
177 
178  xFiFuncDesc->set_label(aBuf);
179  }
180 }
181 
182 /*************************************************************************
183 #* Member: UpdateFunctionList
184 #*------------------------------------------------------------------------
185 #*
186 #* Class: ScFunctionWin
187 #*
188 #* Function: Updates the list of functions depending on the set category
189 #*
190 #* Input: ---
191 #*
192 #* Output: ---
193 #*
194 #************************************************************************/
195 
197 {
198  sal_Int32 nSelPos = xCatBox->get_active();
199  sal_Int32 nCategory = ( -1 != nSelPos )
200  ? (nSelPos-1) : 0;
201 
202  xFuncList->clear();
203  xFuncList->freeze();
204 
205  if ( nSelPos > 0 )
206  {
208 
209  const ScFuncDesc* pDesc = pFuncMgr->First( nCategory );
210  while ( pDesc )
211  {
212  xFuncList->append(OUString::number(reinterpret_cast<sal_Int64>(pDesc)), *(pDesc->mxFuncName));
213  pDesc = pFuncMgr->Next();
214  }
215  }
216  else // LRU list
217  {
219  {
220  if (pDesc)
221  {
222  xFuncList->append(OUString::number(reinterpret_cast<sal_Int64>(pDesc)), pDesc->getFunctionName());
223  }
224  }
225  }
226 
227  xFuncList->thaw();
228 
229  if (xFuncList->n_children() > 0)
230  {
231  xFuncList->set_sensitive(true);
232  xFuncList->select(0);
233  }
234  else
235  {
236  xFuncList->set_sensitive(false);
237  }
238 }
239 
240 /*************************************************************************
241 #* Member: DoEnter
242 #*------------------------------------------------------------------------
243 #*
244 #* Class: ScFunctionWin
245 #*
246 #* Function: Save input into document. Is called after clicking the
247 #* Apply button or a double-click on the function list.
248 #*
249 #* Input: ---
250 #*
251 #* Output: ---
252 #*
253 #************************************************************************/
254 
256 {
257  OUStringBuffer aArgStr;
258  OUString aString=xFuncList->get_selected_text();
260  nArgs=0;
261 
262  if(!aString.isEmpty())
263  {
264  OUString aFirstArgStr;
265  ScModule* pScMod = SC_MOD();
266  ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( pCurSh );
267  ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
268  if(!pScMod->IsEditMode())
269  {
271  pScMod->SetInputMode(SC_INPUT_TABLE);
272  // the above call can result in us being disposed
273  if (xDetectDisposed->isDisposed())
274  return;
275  aString = "=" + xFuncList->get_selected_text();
276  if (pHdl)
277  pHdl->ClearText();
278  }
279  const ScFuncDesc* pDesc =
280  reinterpret_cast<const ScFuncDesc*>(xFuncList->get_selected_id().toInt64());
281  if (pDesc)
282  {
284  UpdateLRUList();
285  nArgs = pDesc->nArgCount;
286  if(nArgs>0)
287  {
288  // NOTE: Theoretically the first parameter could have the
289  // suppress flag as well, but practically it doesn't.
290  aFirstArgStr = pDesc->maDefArgNames[0];
291  aFirstArgStr = comphelper::string::strip(aFirstArgStr, ' ');
292  aFirstArgStr = aFirstArgStr.replaceAll(" ", "_");
293  aArgStr = aFirstArgStr;
294  if ( nArgs != VAR_ARGS && nArgs != PAIRED_VAR_ARGS )
295  { // no VarArgs or Fix plus VarArgs, but not VarArgs only
296  sal_uInt16 nFix;
297  if (nArgs >= PAIRED_VAR_ARGS)
298  nFix = nArgs - PAIRED_VAR_ARGS + 2;
299  else if (nArgs >= VAR_ARGS)
300  nFix = nArgs - VAR_ARGS + 1;
301  else
302  nFix = nArgs;
303  for ( sal_uInt16 nArg = 1;
304  nArg < nFix && !pDesc->pDefArgFlags[nArg].bOptional; nArg++ )
305  {
306  aArgStr.append("; ");
307  OUString sTmp = pDesc->maDefArgNames[nArg];
308  sTmp = comphelper::string::strip(sTmp, ' ');
309  sTmp = sTmp.replaceAll(" ", "_");
310  aArgStr.append(sTmp);
311  }
312  }
313  }
314  }
315  if (pHdl)
316  {
317  if (pHdl->GetEditString().isEmpty())
318  {
319  aString = "=" + xFuncList->get_selected_text();
320  }
321  EditView *pEdView=pHdl->GetActiveView();
322  if(pEdView!=nullptr) // @ needed because of crash during setting a name
323  {
324  if(nArgs>0)
325  {
326  pHdl->InsertFunction(aString);
327  pEdView->InsertText(aArgStr.makeStringAndClear(),true);
328  ESelection aESel=pEdView->GetSelection();
329  aESel.nEndPos = aESel.nStartPos + aFirstArgStr.getLength();
330  pEdView->SetSelection(aESel);
331  pHdl->DataChanged();
332  }
333  else
334  {
335  aString += "()";
336  pEdView->InsertText(aString);
337  pHdl->DataChanged();
338  }
339  }
340  }
341  InitLRUList();
342  }
343  if ( pCurSh )
344  {
345  vcl::Window* pShellWnd = pCurSh->GetWindow();
346 
347  if ( pShellWnd )
348  pShellWnd->GrabFocus();
349  }
350 
351 }
352 
353 /*************************************************************************
354 #* Handle: SelHdl
355 #*------------------------------------------------------------------------
356 #*
357 #* Class: ScFunctionWin
358 #*
359 #* Function: A change of the category will update the list of functions.
360 #*
361 #* Input: ---
362 #*
363 #* Output: ---
364 #*
365 #************************************************************************/
366 
368 {
369  UpdateFunctionList();
370  SetDescription();
371 }
372 
374 {
375  SetDescription();
376 }
377 
378 /*************************************************************************
379 #* Handle: SelHdl
380 #*------------------------------------------------------------------------
381 #*
382 #* Class: ScFunctionWin
383 #*
384 #* Function: A change of the category will update the list of functions.
385 #*
386 #* Input: ---
387 #*
388 #* Output: ---
389 #*
390 #************************************************************************/
391 
392 IMPL_LINK_NOARG( ScFunctionWin, SetSelectionClickHdl, weld::Button&, void )
393 {
394  DoEnter(); // saves the input
395 }
396 
397 IMPL_LINK_NOARG( ScFunctionWin, SetRowActivatedHdl, weld::TreeView&, bool )
398 {
399  DoEnter(); // saves the input
400  return true;
401 }
402 
403 void EnglishFunctionNameChange::setProperty(const css::uno::Any &rProperty)
404 {
405  ConfigurationListenerProperty::setProperty(rProperty);
408 }
409 
410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void InitLRUList()
Definition: dwfunctr.cxx:115
ScFunctionWin(weld::Widget *pParent)
Definition: dwfunctr.cxx:47
#define PAIRED_VAR_ARGS
bool IsEditMode()
Definition: scmod.cxx:1341
#define EMPTY_OUSTRING
Definition: global.hxx:213
bool bOptional
Parameter is optional.
Definition: funcdesc.hxx:211
const OUString & GetEditString()
Definition: inputhdl.cxx:4298
const ScFuncDesc * Next() const
Returns the next function of the current category.
Definition: funcdesc.cxx:1120
OString strip(std::string_view rIn, char c)
sal_uInt16 char char * pDesc
Definition: callform.cxx:57
void SetDescription()
Definition: dwfunctr.cxx:163
void ClearText()
Definition: inputhdl.cxx:3554
aBuf
IMPL_LINK_NOARG(ScFunctionWin, SelComboHdl, weld::ComboBox &, void)
Definition: dwfunctr.cxx:367
Stores spreadsheet functions in categories, including a cumulative ('All') category and makes them ac...
Definition: funcdesc.hxx:305
EditView * GetActiveView()
Definition: inputhdl.cxx:2244
virtual void setProperty(const css::uno::Any &rProperty) override
Definition: dwfunctr.cxx:403
void InsertEntryToLRUList(sal_uInt16 nFIndex)
Definition: scmod.cxx:682
static SfxViewShell * Current()
ScFunctionWin * m_pFunctionWin
Definition: dwfunctr.hxx:31
ParameterFlags * pDefArgFlags
Flags for each parameter.
Definition: funcdesc.hxx:220
sal_Int32 nEndPos
OUString GetParamList() const
Returns list of all parameter names.
Definition: funcdesc.cxx:146
std::unique_ptr< weld::TreeView > xFuncList
Definition: dwfunctr.hxx:47
#define VAR_ARGS
#define SC_MOD()
Definition: scmod.hxx:250
std::unique_ptr< EnglishFunctionNameChange > xConfigChange
Definition: dwfunctr.hxx:52
static ScFunctionMgr * GetStarCalcFunctionMgr()
Definition: global.cxx:618
std::optional< OUString > mxFuncDesc
Description of function.
Definition: funcdesc.hxx:217
void InsertFunction(const OUString &rFuncName, bool bAddPar=true)
Definition: inputhdl.cxx:3507
std::unique_ptr< weld::Button > xInsertButton
Definition: dwfunctr.hxx:48
void GrabFocus()
virtual ~ScFunctionWin() override
Definition: dwfunctr.cxx:89
void InsertText(const OUString &rNew, bool bSelect=false, bool bLOKShowSelect=true)
void SetInputMode(ScInputMode eMode, const OUString *pInitText=nullptr)
Definition: scmod.cxx:1334
void UpdateLRUList()
Definition: dwfunctr.cxx:140
rtl::Reference< comphelper::ConfigurationListener > xConfigListener
Definition: dwfunctr.hxx:51
virtual void fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription * > &_rLastRUFunctions) const override
Appends the last recently used functions.
Definition: funcdesc.cxx:1149
std::optional< OUString > mxFuncName
Function name.
Definition: funcdesc.hxx:216
virtual void initArgumentInfo() const override
Requests function data from AddInCollection.
Definition: funcdesc.cxx:327
sal_uInt16 nFIndex
Unique function index.
Definition: funcdesc.hxx:221
void DataChanged(bool bFromTopNotify=false, bool bSetModified=true)
Definition: inputhdl.cxx:2610
const ScFuncDesc * pFuncDesc
Definition: dwfunctr.hxx:53
vcl::Window * GetWindow() const
void SetSelection(const ESelection &rNewSel)
std::unique_ptr< weld::ComboBox > xCatBox
Definition: dwfunctr.hxx:46
ESelection GetSelection() const
std::vector< OUString > maDefArgNames
Parameter name(s)
Definition: funcdesc.hxx:218
ScInputHandler * GetInputHdl(ScTabViewShell *pViewSh=nullptr, bool bUseRef=true)
Input-Handler.
Definition: scmod.cxx:1303
std::unique_ptr< weld::Label > xFiFuncDesc
Definition: dwfunctr.hxx:49
void DoEnter()
Definition: dwfunctr.cxx:255
sal_uInt16 nArgs
Definition: dwfunctr.hxx:54
Stores and generates human readable descriptions for spreadsheet-functions, e.g. functions used in fo...
Definition: funcdesc.hxx:40
sal_uInt16 nArgCount
All parameter count, suppressed and unsuppressed.
Definition: funcdesc.hxx:223
void UpdateFunctionList()
Definition: dwfunctr.cxx:196
::std::vector< const formula::IFunctionDescription * > aLRUList
Definition: dwfunctr.hxx:56
const ScFuncDesc * First(sal_uInt16 nCategory=0) const
Returns the first function in category nCategory.
Definition: funcdesc.cxx:1102
sal_Int32 nStartPos