LibreOffice Module formula (master) 1
funcpage.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 <vcl/event.hxx>
21#include <vcl/svapp.hxx>
23
24#include "funcpage.hxx"
27
28namespace formula
29{
30IMPL_LINK(FuncPage, KeyInputHdl, const KeyEvent&, rKEvt, bool)
31{
32 if (rKEvt.GetCharCode() == ' ')
33 {
34 aDoubleClickLink.Call(*this);
35 return true;
36 }
37 return false;
38}
39
40// tdf#104487 - remember last used function category - set default to All category
42
43FuncPage::FuncPage(weld::Container* pParent, const IFunctionManager* _pFunctionManager)
44 : m_xBuilder(Application::CreateBuilder(pParent, "formula/ui/functionpage.ui"))
45 , m_xContainer(m_xBuilder->weld_container("FunctionPage"))
46 , m_xLbCategory(m_xBuilder->weld_combo_box("category"))
47 , m_xLbFunction(m_xBuilder->weld_tree_view("function"))
48 , m_xLbFunctionSearchString(m_xBuilder->weld_entry("search"))
49 , m_pFunctionManager(_pFunctionManager)
50{
51 m_xLbFunction->make_sorted();
52 m_aHelpId = m_xLbFunction->get_help_id();
53
55
56 const sal_uInt32 nCategoryCount = m_pFunctionManager->getCount();
57 for (sal_uInt32 j = 0; j < nCategoryCount; ++j)
58 {
60 OUString sId(weld::toId(pCategory));
61 m_xLbCategory->append(sId, pCategory->getName());
62 }
63
64 // tdf#104487 - remember last used function category
66 OUString searchStr = m_xLbFunctionSearchString->get_text();
67 UpdateFunctionList(searchStr);
68 // lock to its initial size
69 m_xLbFunction->set_size_request(m_xLbFunction->get_preferred_size().Width(),
70 m_xLbFunction->get_height_rows(15));
71 m_xLbCategory->connect_changed(LINK(this, FuncPage, SelComboBoxHdl));
72 m_xLbFunction->connect_changed(LINK(this, FuncPage, SelTreeViewHdl));
73 m_xLbFunction->connect_row_activated(LINK(this, FuncPage, DblClkHdl));
74 m_xLbFunction->connect_key_press(LINK(this, FuncPage, KeyInputHdl));
75 m_xLbFunctionSearchString->connect_changed(LINK(this, FuncPage, ModifyHdl));
76
77 m_xLbFunctionSearchString->grab_focus();
78}
79
81
83{
84 const sal_uInt32 nCount = _pCategory->getCount();
85 for (sal_uInt32 i = 0; i < nCount; ++i)
86 {
87 TFunctionDesc pDesc(_pCategory->getFunction(i));
88 if (!pDesc->isHidden())
89 {
90 OUString sId(weld::toId(pDesc));
91 m_xLbFunction->append(sId, pDesc->getFunctionName());
92 }
93 }
94}
95
96//aStr is non-empty when user types in the search box to search some function
97void FuncPage::UpdateFunctionList(const OUString& aStr)
98{
99 m_xLbFunction->clear();
100 m_xLbFunction->freeze();
101
102 const sal_Int32 nSelPos = m_xLbCategory->get_active();
103 // tdf#104487 - remember last used function category
105
106 if (aStr.isEmpty() || nSelPos == 0)
107 {
108 const IFunctionCategory* pCategory
109 = weld::fromId<const IFunctionCategory*>(m_xLbCategory->get_id(nSelPos));
110
111 if (nSelPos > 0)
112 {
113 if (pCategory == nullptr)
114 {
115 const sal_uInt32 nCount = m_pFunctionManager->getCount();
116 for (sal_uInt32 i = 0; i < nCount; ++i)
117 {
119 }
120 }
121 else
122 {
123 impl_addFunctions(pCategory);
124 }
125 }
126 else // LRU-List
127 {
128 for (auto const& elem : aLRUList)
129 {
130 if (elem) // may be null if a function is no longer available
131 {
132 OUString sId(weld::toId(elem));
133 m_xLbFunction->append(sId, elem->getFunctionName());
134 }
135 }
136 }
137 }
138 else
139 {
140 SvtSysLocale aSysLocale;
141 const CharClass& rCharClass = aSysLocale.GetCharClass();
142 const OUString aSearchStr(rCharClass.uppercase(aStr));
143
144 const sal_uInt32 nCategoryCount = m_pFunctionManager->getCount();
145 // Category listbox holds additional entries for Last Used and All, so
146 // the offset should be two but hard coded numbers are ugly...
147 const sal_Int32 nCategoryOffset = m_xLbCategory->get_count() - nCategoryCount;
148 // If a real category (not Last Used or All) is selected, list only
149 // functions of that category. Else list all, LRU is handled above.
150 sal_Int32 nCatBeg = (nSelPos == -1 ? -1 : nSelPos - nCategoryOffset);
151 sal_uInt32 nCatEnd;
152 if (nCatBeg < 0)
153 {
154 nCatBeg = 0;
155 nCatEnd = nCategoryCount;
156 }
157 else
158 {
159 nCatEnd = nCatBeg + 1;
160 }
161 for (sal_uInt32 i = nCatBeg; i < nCatEnd; ++i)
162 {
164 const sal_uInt32 nFunctionCount = pCategory->getCount();
165 for (sal_uInt32 j = 0; j < nFunctionCount; ++j)
166 {
167 TFunctionDesc pDesc(pCategory->getFunction(j));
168 // tdf#146781 - search for the desired function also in the description
169 if (rCharClass.uppercase(pDesc->getFunctionName()).indexOf(aSearchStr) >= 0
170 || rCharClass.uppercase(pDesc->getDescription()).indexOf(aSearchStr) >= 0)
171 {
172 if (!pDesc->isHidden())
173 {
174 OUString sId(weld::toId(pDesc));
175 m_xLbFunction->append(sId, pDesc->getFunctionName());
176 }
177 }
178 }
179 }
180 }
181
182 m_xLbFunction->thaw();
183 // Ensure no function is selected so the Next button doesn't overwrite a
184 // function that is not in the list with an arbitrary selected one.
185 m_xLbFunction->unselect_all();
186
187 if (IsVisible())
188 SelTreeViewHdl(*m_xLbFunction);
189}
190
192{
193 OUString searchStr = m_xLbFunctionSearchString->get_text();
194 m_xLbFunction->set_help_id(m_aHelpId);
195 UpdateFunctionList(searchStr);
196}
197
199{
200 const IFunctionDescription* pDesc = GetFuncDesc(GetFunction());
201 if (pDesc)
202 {
203 const OUString sHelpId = pDesc->getHelpId();
204 if (!sHelpId.isEmpty())
205 m_xLbFunction->set_help_id(sHelpId);
206 }
207 aSelectionLink.Call(*this);
208}
209
211{
212 aDoubleClickLink.Call(*this);
213 return true;
214}
215
217{
218 // While typing select All category.
219 m_xLbCategory->set_active(1);
220 OUString searchStr = m_xLbFunctionSearchString->get_text();
221 UpdateFunctionList(searchStr);
222}
223
224void FuncPage::SetCategory(sal_Int32 nCat)
225{
226 // tdf#104487 - remember last used function category
228 m_xLbCategory->set_active(nCat);
229 UpdateFunctionList(OUString());
230}
231
233{
234 return m_xLbFunction->find_id(weld::toId(_pDesc));
235}
236
237void FuncPage::SetFunction(sal_Int32 nFunc)
238{
239 if (nFunc == -1)
240 m_xLbFunction->unselect_all();
241 else
242 m_xLbFunction->select(nFunc);
243}
244
245void FuncPage::SetFocus() { m_xLbFunction->grab_focus(); }
246
247sal_Int32 FuncPage::GetCategory() const { return m_xLbCategory->get_active(); }
248
249sal_Int32 FuncPage::GetCategoryEntryCount() const { return m_xLbCategory->get_count(); }
250
251sal_Int32 FuncPage::GetFunction() const { return m_xLbFunction->get_selected_index(); }
252
253sal_Int32 FuncPage::GetFunctionEntryCount() const { return m_xLbFunction->n_children(); }
254
255OUString FuncPage::GetSelFunctionName() const { return m_xLbFunction->get_selected_text(); }
256
257const IFunctionDescription* FuncPage::GetFuncDesc(sal_Int32 nPos) const
258{
259 if (nPos == -1)
260 return nullptr;
261 // not pretty, but hopefully rare
262 return weld::fromId<const IFunctionDescription*>(m_xLbFunction->get_id(nPos));
263}
264
265} // formula
266
267/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
const CharClass & GetCharClass() const
static sal_Int32 m_nRememberedFunctionCategory
Definition: funcpage.hxx:52
std::unique_ptr< weld::Entry > m_xLbFunctionSearchString
Definition: funcpage.hxx:42
const IFunctionManager * m_pFunctionManager
Definition: funcpage.hxx:46
std::unique_ptr< weld::ComboBox > m_xLbCategory
Definition: funcpage.hxx:40
std::unique_ptr< weld::TreeView > m_xLbFunction
Definition: funcpage.hxx:41
OUString m_aHelpId
Definition: funcpage.hxx:49
sal_Int32 GetCategoryEntryCount() const
Definition: funcpage.cxx:249
OUString GetSelFunctionName() const
Definition: funcpage.cxx:255
::std::vector< TFunctionDesc > aLRUList
Definition: funcpage.hxx:48
bool IsVisible() const
Definition: funcpage.hxx:88
void impl_addFunctions(const IFunctionCategory *_pCategory)
Definition: funcpage.cxx:82
sal_Int32 GetFunctionEntryCount() const
Definition: funcpage.cxx:253
sal_Int32 GetFuncPos(const IFunctionDescription *_pDesc)
Definition: funcpage.cxx:232
void UpdateFunctionList(const OUString &)
Definition: funcpage.cxx:97
sal_Int32 GetCategory() const
Definition: funcpage.cxx:247
void SetFunction(sal_Int32 nFunc)
Definition: funcpage.cxx:237
FuncPage(weld::Container *pContainer, const IFunctionManager *_pFunctionManager)
Definition: funcpage.cxx:43
const IFunctionDescription * GetFuncDesc(sal_Int32 nPos) const
Definition: funcpage.cxx:257
void SetCategory(sal_Int32 nCat)
Definition: funcpage.cxx:224
sal_Int32 GetFunction() const
Definition: funcpage.cxx:251
virtual const IFunctionDescription * getFunction(sal_uInt32 _nPos) const =0
virtual sal_uInt32 getCount() const =0
virtual OUString getName() const =0
virtual bool isHidden() const =0
virtual OUString getFunctionName() const =0
virtual OUString getDescription() const =0
virtual OUString getHelpId() const =0
virtual const IFunctionCategory * getCategory(sal_uInt32 nPos) const =0
virtual sal_uInt32 getCount() const =0
virtual void fillLastRecentlyUsedFunctions(::std::vector< const IFunctionDescription * > &_rLastRUFunctions) const =0
int nCount
sal_uInt16 nPos
aStr
IMPL_LINK_NOARG(FormulaDlg_Impl, DblClkHdl, FuncPage &, void)
Definition: formula.cxx:1065
IMPL_LINK(FormulaDlg_Impl, BtnHdl, weld::Button &, rBtn, void)
Definition: formula.cxx:1022
int i
OUString toId(const void *pValue)
Reference< XNameAccess > m_xContainer
OUString sId