Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / formula / source / ui / dlg / funcpage.cxx
blob92035c709a3d42f5c2ef4d6844a1a4c69e89a823
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <sfx2/dispatch.hxx>
21 #include <sfx2/docfile.hxx>
22 #include <svl/zforlist.hxx>
23 #include <svl/stritem.hxx>
24 #include <vcl/event.hxx>
25 #include <vcl/svapp.hxx>
26 #include <formula/IFunctionDescription.hxx>
28 #include "funcpage.hxx"
29 #include <unotools/syslocale.hxx>
30 #include <unotools/charclass.hxx>
32 namespace formula
35 IMPL_LINK(FuncPage, KeyInputHdl, const KeyEvent&, rKEvt, bool)
37 if (rKEvt.GetCharCode() == ' ')
39 aDoubleClickLink.Call(*this);
40 return true;
42 return false;
45 FuncPage::FuncPage(weld::Container* pParent, const IFunctionManager* _pFunctionManager)
46 : m_xBuilder(Application::CreateBuilder(pParent, "formula/ui/functionpage.ui"))
47 , m_xContainer(m_xBuilder->weld_container("FunctionPage"))
48 , m_xLbCategory(m_xBuilder->weld_combo_box("category"))
49 , m_xLbFunction(m_xBuilder->weld_tree_view("function"))
50 , m_xLbFunctionSearchString(m_xBuilder->weld_entry("search"))
51 , m_pFunctionManager(_pFunctionManager)
53 m_xLbFunction->make_sorted();
54 m_aHelpId = m_xLbFunction->get_help_id();
56 m_pFunctionManager->fillLastRecentlyUsedFunctions(aLRUList);
58 const sal_uInt32 nCategoryCount = m_pFunctionManager->getCount();
59 for(sal_uInt32 j= 0; j < nCategoryCount; ++j)
61 const IFunctionCategory* pCategory = m_pFunctionManager->getCategory(j);
62 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pCategory)));
63 m_xLbCategory->append(sId, pCategory->getName());
66 m_xLbCategory->set_active(1);
67 OUString searchStr = m_xLbFunctionSearchString->get_text();
68 UpdateFunctionList(searchStr);
69 // lock to its initial size
70 m_xLbFunction->set_size_request(m_xLbFunction->get_preferred_size().Width(),
71 m_xLbFunction->get_height_rows(15));
72 m_xLbCategory->connect_changed( LINK( this, FuncPage, SelComboBoxHdl ) );
73 m_xLbFunction->connect_changed( LINK( this, FuncPage, SelTreeViewHdl ) );
74 m_xLbFunction->connect_row_activated( LINK( this, FuncPage, DblClkHdl ) );
75 m_xLbFunction->connect_key_press( LINK( this, FuncPage, KeyInputHdl ) );
76 m_xLbFunctionSearchString->connect_changed( LINK( this, FuncPage, ModifyHdl ) );
79 FuncPage::~FuncPage()
83 void FuncPage::impl_addFunctions(const IFunctionCategory* _pCategory)
85 const sal_uInt32 nCount = _pCategory->getCount();
86 for(sal_uInt32 i = 0 ; i < nCount; ++i)
88 TFunctionDesc pDesc(_pCategory->getFunction(i));
89 if (!pDesc->isHidden())
91 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pDesc)));
92 m_xLbFunction->append(sId, pDesc->getFunctionName());
97 //aStr is non-empty when user types in the search box to search some function
98 void FuncPage::UpdateFunctionList(const OUString& aStr)
100 m_xLbFunction->clear();
101 m_xLbFunction->freeze();
103 const sal_Int32 nSelPos = m_xLbCategory->get_active();
105 if (aStr.isEmpty() || nSelPos == 0)
107 const IFunctionCategory* pCategory = reinterpret_cast<const IFunctionCategory*>(m_xLbCategory->get_id(nSelPos).toInt64());
109 if ( nSelPos > 0 )
111 if ( pCategory == nullptr )
113 const sal_uInt32 nCount = m_pFunctionManager->getCount();
114 for(sal_uInt32 i = 0 ; i < nCount; ++i)
116 impl_addFunctions(m_pFunctionManager->getCategory(i));
119 else
121 impl_addFunctions(pCategory);
124 else // LRU-List
126 for (auto const& elem : aLRUList)
128 if (elem) // may be null if a function is no longer available
130 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(elem)));
131 m_xLbFunction->append(sId, elem->getFunctionName());
136 else
138 SvtSysLocale aSysLocale;
139 const CharClass* pCharClass = aSysLocale.GetCharClassPtr();
140 const OUString aSearchStr( pCharClass->uppercase(aStr));
142 const sal_uInt32 nCategoryCount = m_pFunctionManager->getCount();
143 // Category listbox holds additional entries for Last Used and All, so
144 // the offset should be two but hard coded numbers are ugly...
145 const sal_Int32 nCategoryOffset = m_xLbCategory->get_count() - nCategoryCount;
146 // If a real category (not Last Used or All) is selected, list only
147 // functions of that category. Else list all, LRU is handled above.
148 sal_Int32 nCatBeg = (nSelPos == -1 ? -1 : nSelPos - nCategoryOffset);
149 sal_uInt32 nCatEnd;
150 if (nCatBeg < 0)
152 nCatBeg = 0;
153 nCatEnd = nCategoryCount;
155 else
157 nCatEnd = nCatBeg + 1;
159 for (sal_uInt32 i = nCatBeg; i < nCatEnd; ++i)
161 const IFunctionCategory* pCategory = m_pFunctionManager->getCategory(i);
162 const sal_uInt32 nFunctionCount = pCategory->getCount();
163 for (sal_uInt32 j = 0; j < nFunctionCount; ++j)
165 TFunctionDesc pDesc(pCategory->getFunction(j));
166 if (pCharClass->uppercase(pDesc->getFunctionName()).indexOf(aSearchStr) >= 0)
168 if (!pDesc->isHidden())
170 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pDesc)));
171 m_xLbFunction->append(sId, pDesc->getFunctionName());
178 m_xLbFunction->thaw();
179 // Ensure no function is selected so the Next button doesn't overwrite a
180 // function that is not in the list with an arbitrary selected one.
181 m_xLbFunction->unselect_all();
183 if (IsVisible())
184 SelTreeViewHdl(*m_xLbFunction);
187 IMPL_LINK_NOARG(FuncPage, SelComboBoxHdl, weld::ComboBox&, void)
189 OUString searchStr = m_xLbFunctionSearchString->get_text();
190 m_xLbFunction->set_help_id(m_aHelpId);
191 UpdateFunctionList(searchStr);
194 IMPL_LINK_NOARG(FuncPage, SelTreeViewHdl, weld::TreeView&, void)
196 const IFunctionDescription* pDesc = GetFuncDesc( GetFunction() );
197 if ( pDesc )
199 const OString sHelpId = pDesc->getHelpId();
200 if ( !sHelpId.isEmpty() )
201 m_xLbFunction->set_help_id(sHelpId);
203 aSelectionLink.Call(*this);
206 IMPL_LINK_NOARG(FuncPage, DblClkHdl, weld::TreeView&, bool)
208 aDoubleClickLink.Call(*this);
209 return true;
212 IMPL_LINK_NOARG(FuncPage, ModifyHdl, weld::Entry&, void)
214 // While typing select All category.
215 m_xLbCategory->set_active(1);
216 OUString searchStr = m_xLbFunctionSearchString->get_text();
217 UpdateFunctionList(searchStr);
220 void FuncPage::SetCategory(sal_Int32 nCat)
222 m_xLbCategory->set_active(nCat);
223 UpdateFunctionList(OUString());
226 sal_Int32 FuncPage::GetFuncPos(const IFunctionDescription* _pDesc)
228 return m_xLbFunction->find_id(OUString::number(reinterpret_cast<sal_Int64>(_pDesc)));
231 void FuncPage::SetFunction(sal_Int32 nFunc)
233 if (nFunc == -1)
234 m_xLbFunction->unselect_all();
235 else
236 m_xLbFunction->select(nFunc);
239 void FuncPage::SetFocus()
241 m_xLbFunction->grab_focus();
244 sal_Int32 FuncPage::GetCategory() const
246 return m_xLbCategory->get_active();
249 sal_Int32 FuncPage::GetFunction() const
251 return m_xLbFunction->get_selected_index();
254 sal_Int32 FuncPage::GetFunctionEntryCount() const
256 return m_xLbFunction->n_children();
259 OUString FuncPage::GetSelFunctionName() const
261 return m_xLbFunction->get_selected_text();
264 const IFunctionDescription* FuncPage::GetFuncDesc( sal_Int32 nPos ) const
266 if (nPos == -1)
267 return nullptr;
268 // not pretty, but hopefully rare
269 return reinterpret_cast<const IFunctionDescription*>(m_xLbFunction->get_id(nPos).toInt64());
272 } // formula
274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */