formula/source/ui/dlg/formula.cxx     |    8 --
 formula/source/ui/dlg/funcpage.cxx    |   73 ++++++++++++++++++----
 formula/source/ui/dlg/funcpage.hxx    |    8 +-
 formula/uiconfig/ui/functionpage.ui   |    2 
 sc/source/ui/formdlg/dwfunctr.cxx     |  112 +++++++++++++++++++++++++++-------
 sc/source/ui/inc/dwfunctr.hxx         |    6 +
 sc/uiconfig/scalc/ui/functionpanel.ui |    2 
 7 files changed, 168 insertions(+), 43 deletions(-)

New commits:
commit 5bd284583fe1f891bac3192d8e20083a57830a0a
Author:     AhmedHamed <ahmedhamed3...@gmail.com>
AuthorDate: Thu Jun 27 15:07:24 2024 +0300
Commit:     Andreas Heinisch <andreas.heini...@yahoo.de>
CommitDate: Fri Jul 19 07:50:55 2024 +0200

    tdf#161296 Convert functions list in FD & FW into collapsible sections
    
    Change-Id: I9211c0cf02be8d21e343d57f53d14e50d7b5fd0d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169639
    Reviewed-by: Andreas Heinisch <andreas.heini...@yahoo.de>
    Tested-by: Jenkins

diff --git a/formula/source/ui/dlg/formula.cxx 
b/formula/source/ui/dlg/formula.cxx
index 0edc5b78420c..1d1b3c6c624e 100644
--- a/formula/source/ui/dlg/formula.cxx
+++ b/formula/source/ui/dlg/formula.cxx
@@ -1034,7 +1034,7 @@ IMPL_LINK(FormulaDlg_Impl, BtnHdl, weld::Button&, rBtn, 
void)
         const IFunctionDescription* pDesc;
         sal_Int32 nSelFunc = m_xFuncPage->GetFunction();
         if (nSelFunc != -1)
-            pDesc = m_xFuncPage->GetFuncDesc( nSelFunc );
+            pDesc = m_xFuncPage->GetFuncDesc();
         else
         {
             // Do not overwrite the selected formula expression, just edit the
@@ -1064,10 +1064,8 @@ IMPL_LINK(FormulaDlg_Impl, BtnHdl, weld::Button&, rBtn, 
void)
 
 IMPL_LINK_NOARG( FormulaDlg_Impl, DblClkHdl, FuncPage&, void)
 {
-    sal_Int32 nFunc = m_xFuncPage->GetFunction();
-
     //  ex-UpdateLRUList
-    const IFunctionDescription* pDesc = m_xFuncPage->GetFuncDesc(nFunc);
+    const IFunctionDescription* pDesc = m_xFuncPage->GetFuncDesc();
     m_pHelper->insertEntryToLRUList(pDesc);
 
     OUString aFuncName = m_xFuncPage->GetSelFunctionName() + "()";
@@ -1672,7 +1670,7 @@ IMPL_LINK_NOARG( FormulaDlg_Impl, FuncSelHdl, FuncPage&, 
void)
     if (   (m_xFuncPage->GetFunctionEntryCount() > 0)
         && (m_xFuncPage->GetFunction() != -1) )
     {
-        const IFunctionDescription* pDesc = m_xFuncPage->GetFuncDesc( 
m_xFuncPage->GetFunction() );
+        const IFunctionDescription* pDesc = m_xFuncPage->GetFuncDesc();
 
         if (pDesc != m_pFuncDesc)
             m_xBtnForward->set_sensitive(true); //new
diff --git a/formula/source/ui/dlg/funcpage.cxx 
b/formula/source/ui/dlg/funcpage.cxx
index c66e5f0cfb36..c844a29f612e 100644
--- a/formula/source/ui/dlg/funcpage.cxx
+++ b/formula/source/ui/dlg/funcpage.cxx
@@ -46,6 +46,7 @@ FuncPage::FuncPage(weld::Container* pParent, const 
IFunctionManager* _pFunctionM
     , m_xContainer(m_xBuilder->weld_container(u"FunctionPage"_ustr))
     , m_xLbCategory(m_xBuilder->weld_combo_box(u"category"_ustr))
     , m_xLbFunction(m_xBuilder->weld_tree_view(u"function"_ustr))
+    , m_xScratchIter(m_xLbFunction->make_iterator())
     , m_xLbFunctionSearchString(m_xBuilder->weld_entry(u"search"_ustr))
     , m_xHelpButton(m_xBuilder->weld_button(u"help"_ustr))
     , m_pFunctionManager(_pFunctionManager)
@@ -83,16 +84,35 @@ FuncPage::FuncPage(weld::Container* pParent, const 
IFunctionManager* _pFunctionM
 
 FuncPage::~FuncPage() {}
 
-void FuncPage::impl_addFunctions(const IFunctionCategory* _pCategory)
+weld::TreeIter* FuncPage::FillCategoriesMap(const OUString& aCategory, bool 
bFill)
 {
+    if (!bFill)
+        return nullptr;
+
+    if (mCategories.find(aCategory) == mCategories.end())
+    {
+        mCategories[aCategory] = m_xLbFunction->make_iterator();
+        m_xLbFunction->insert(nullptr, -1, &aCategory, nullptr, nullptr, 
nullptr, false,
+                              mCategories[aCategory].get());
+    }
+    return mCategories[aCategory].get();
+}
+
+void FuncPage::impl_addFunctions(const IFunctionCategory* _pCategory, bool 
bFillCategories)
+{
+    weld::TreeIter* pCategoryIter = FillCategoriesMap(_pCategory->getName(), 
bFillCategories);
+
     const sal_uInt32 nCount = _pCategory->getCount();
     for (sal_uInt32 i = 0; i < nCount; ++i)
     {
         TFunctionDesc pDesc(_pCategory->getFunction(i));
         if (!pDesc->isHidden())
         {
+            OUString aFunction(pDesc->getFunctionName());
             OUString sId(weld::toId(pDesc));
-            m_xLbFunction->append(sId, pDesc->getFunctionName());
+
+            m_xLbFunction->insert(pCategoryIter, -1, &aFunction, &sId, 
nullptr, nullptr, false,
+                                  m_xScratchIter.get());
         }
     }
 }
@@ -102,12 +122,15 @@ void FuncPage::UpdateFunctionList(const OUString& aStr)
 {
     m_xLbFunction->clear();
     m_xLbFunction->freeze();
+    mCategories.clear();
 
     const sal_Int32 nSelPos = m_xLbCategory->get_active();
+    bool bCollapse = nSelPos == 1;
+    bool bFilter = !aStr.isEmpty();
     // tdf#104487 - remember last used function category
     m_nRememberedFunctionCategory = nSelPos;
 
-    if (aStr.isEmpty() || nSelPos == 0)
+    if (!bFilter || nSelPos == 0)
     {
         const IFunctionCategory* pCategory
             = weld::fromId<const 
IFunctionCategory*>(m_xLbCategory->get_id(nSelPos));
@@ -119,12 +142,12 @@ void FuncPage::UpdateFunctionList(const OUString& aStr)
                 const sal_uInt32 nCount = m_pFunctionManager->getCount();
                 for (sal_uInt32 i = 0; i < nCount; ++i)
                 {
-                    impl_addFunctions(m_pFunctionManager->getCategory(i));
+                    impl_addFunctions(m_pFunctionManager->getCategory(i), 
bCollapse);
                 }
             }
             else
             {
-                impl_addFunctions(pCategory);
+                impl_addFunctions(pCategory, false);
             }
         }
         else // LRU-List
@@ -133,8 +156,11 @@ void FuncPage::UpdateFunctionList(const OUString& aStr)
             {
                 if (elem) // may be null if a function is no longer available
                 {
+                    OUString aFunction(elem->getFunctionName());
                     OUString sId(weld::toId(elem));
-                    m_xLbFunction->append(sId, elem->getFunctionName());
+
+                    m_xLbFunction->insert(nullptr, -1, &aFunction, &sId, 
nullptr, nullptr, false,
+                                          m_xScratchIter.get());
                 }
             }
         }
@@ -175,8 +201,13 @@ void FuncPage::UpdateFunctionList(const OUString& aStr)
                 {
                     if (!pDesc->isHidden())
                     {
+                        OUString aFunction(pDesc->getFunctionName());
                         OUString sId(weld::toId(pDesc));
-                        m_xLbFunction->append(sId, pDesc->getFunctionName());
+
+                        weld::TreeIter* pCategoryIter
+                            = FillCategoriesMap(pCategory->getName(), 
bCollapse);
+                        m_xLbFunction->insert(pCategoryIter, -1, &aFunction, 
&sId, nullptr, nullptr,
+                                              false, m_xScratchIter.get());
                     }
                 }
             }
@@ -188,12 +219,19 @@ void FuncPage::UpdateFunctionList(const OUString& aStr)
     // function that is not in the list with an arbitrary selected one.
     m_xLbFunction->unselect_all();
 
+    if (bCollapse && bFilter)
+    {
+        for (const auto& category : mCategories)
+            m_xLbFunction->expand_row(*category.second);
+    }
+
     if (IsVisible())
         SelTreeViewHdl(*m_xLbFunction);
 }
 
 IMPL_LINK_NOARG(FuncPage, SelComboBoxHdl, weld::ComboBox&, void)
 {
+    m_xLbFunctionSearchString->set_sensitive(m_xLbCategory->get_active() > 0);
     OUString searchStr = m_xLbFunctionSearchString->get_text();
     m_xLbFunction->set_help_id(m_aHelpId);
     UpdateFunctionList(searchStr);
@@ -202,7 +240,7 @@ IMPL_LINK_NOARG(FuncPage, SelComboBoxHdl, weld::ComboBox&, 
void)
 
 IMPL_LINK_NOARG(FuncPage, SelTreeViewHdl, weld::TreeView&, void)
 {
-    const IFunctionDescription* pDesc = GetFuncDesc(GetFunction());
+    const IFunctionDescription* pDesc = GetFuncDesc();
     if (pDesc)
     {
         const OUString sHelpId = pDesc->getHelpId();
@@ -216,14 +254,23 @@ IMPL_LINK_NOARG(FuncPage, SelTreeViewHdl, 
weld::TreeView&, void)
 
 IMPL_LINK_NOARG(FuncPage, DblClkHdl, weld::TreeView&, bool)
 {
+    const OUString aString = m_xLbFunction->get_selected_text();
+    if (mCategories.find(aString) != mCategories.end())
+    {
+        const auto& categoryRow = *(mCategories[aString]);
+        if (m_xLbFunction->get_row_expanded(categoryRow))
+            m_xLbFunction->collapse_row(categoryRow);
+        else
+            m_xLbFunction->expand_row(categoryRow);
+        return true;
+    }
+    m_xLbFunctionSearchString->set_text(OUString());
     aDoubleClickLink.Call(*this);
     return true;
 }
 
 IMPL_LINK_NOARG(FuncPage, ModifyHdl, weld::Entry&, void)
 {
-    // While typing select All category.
-    m_xLbCategory->set_active(1);
     OUString searchStr = m_xLbFunctionSearchString->get_text();
     UpdateFunctionList(searchStr);
 }
@@ -277,12 +324,12 @@ sal_Int32 FuncPage::GetFunctionEntryCount() const { 
return m_xLbFunction->n_chil
 
 OUString FuncPage::GetSelFunctionName() const { return 
m_xLbFunction->get_selected_text(); }
 
-const IFunctionDescription* FuncPage::GetFuncDesc(sal_Int32 nPos) const
+const IFunctionDescription* FuncPage::GetFuncDesc() const
 {
-    if (nPos == -1)
+    if (GetFunction() == -1)
         return nullptr;
     // not pretty, but hopefully rare
-    return weld::fromId<const 
IFunctionDescription*>(m_xLbFunction->get_id(nPos));
+    return weld::fromId<const 
IFunctionDescription*>(m_xLbFunction->get_selected_id());
 }
 
 } // formula
diff --git a/formula/source/ui/dlg/funcpage.hxx 
b/formula/source/ui/dlg/funcpage.hxx
index 45d5d19b75f9..0df77e1b156b 100644
--- a/formula/source/ui/dlg/funcpage.hxx
+++ b/formula/source/ui/dlg/funcpage.hxx
@@ -21,6 +21,7 @@
 
 #include <vcl/weld.hxx>
 #include <vector>
+#include <unordered_map>
 
 namespace formula
 {
@@ -39,6 +40,7 @@ private:
 
     std::unique_ptr<weld::ComboBox> m_xLbCategory;
     std::unique_ptr<weld::TreeView> m_xLbFunction;
+    std::unique_ptr<weld::TreeIter> m_xScratchIter;
     std::unique_ptr<weld::Entry> m_xLbFunctionSearchString;
     std::unique_ptr<weld::Button> m_xHelpButton;
 
@@ -47,12 +49,14 @@ private:
     const IFunctionManager*  m_pFunctionManager;
 
     ::std::vector< TFunctionDesc >  aLRUList;
+    ::std::unordered_map<OUString, std::unique_ptr<weld::TreeIter>> 
mCategories;
     OUString    m_aHelpId;
 
     // tdf#104487 - remember last used function category
     static sal_Int32 m_nRememberedFunctionCategory;
 
-    void impl_addFunctions(const IFunctionCategory* _pCategory);
+    void impl_addFunctions(const IFunctionCategory*, bool);
+    weld::TreeIter* FillCategoriesMap(const OUString&, bool);
 
     DECL_LINK(SelComboBoxHdl, weld::ComboBox&, void);
     DECL_LINK(SelTreeViewHdl, weld::TreeView&, void);
@@ -80,7 +84,7 @@ public:
     static sal_Int32 GetRememeberdFunctionCategory() { return 
m_nRememberedFunctionCategory; };
 
     sal_Int32       GetFuncPos(const IFunctionDescription* _pDesc);
-    const IFunctionDescription* GetFuncDesc( sal_Int32  nPos ) const;
+    const IFunctionDescription* GetFuncDesc() const;
     OUString        GetSelFunctionName() const;
 
     void            SetDoubleClickHdl( const Link<FuncPage&,void>& rLink ) { 
aDoubleClickLink = rLink; }
diff --git a/formula/uiconfig/ui/functionpage.ui 
b/formula/uiconfig/ui/functionpage.ui
index aa1e2ce08e3b..247e4c4fce4d 100644
--- a/formula/uiconfig/ui/functionpage.ui
+++ b/formula/uiconfig/ui/functionpage.ui
@@ -120,7 +120,7 @@
             <property name="model">liststore1</property>
             <property name="headers-visible">False</property>
             <property name="search-column">0</property>
-            <property name="show-expanders">False</property>
+            <property name="show-expanders">True</property>
             <child internal-child="selection">
               <object class="GtkTreeSelection"/>
             </child>
diff --git a/sc/source/ui/formdlg/dwfunctr.cxx 
b/sc/source/ui/formdlg/dwfunctr.cxx
index ba59abccee9f..f2665e017831 100644
--- a/sc/source/ui/formdlg/dwfunctr.cxx
+++ b/sc/source/ui/formdlg/dwfunctr.cxx
@@ -51,6 +51,7 @@ ScFunctionWin::ScFunctionWin(weld::Widget* pParent)
     : 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))
+    , xScratchIter(xFuncList->make_iterator())
     , xInsertButton(m_xBuilder->weld_button(u"insert"_ustr))
     , xHelpButton(m_xBuilder->weld_button(u"help"_ustr))
     , xFiFuncDesc(m_xBuilder->weld_text_view(u"funcdesc"_ustr))
@@ -135,6 +136,35 @@ void ScFunctionWin::InitLRUList()
         UpdateFunctionList(u""_ustr);
 }
 
+
+/*************************************************************************
+#*  Member:     FillCategoriesMap
+#*------------------------------------------------------------------------
+#*
+#*  Class:      ScFunctionWin
+#*
+#*  Function:   Fills the categories map.
+#*
+#*  Input:      ---
+#*
+#*  Output:     ---
+#*
+#************************************************************************/
+
+weld::TreeIter* ScFunctionWin::FillCategoriesMap(const OUString& aCategory, 
bool bFill)
+{
+    if (!bFill)
+        return nullptr;
+
+    if (mCategories.find(aCategory) == mCategories.end())
+    {
+        mCategories[aCategory] = xFuncList->make_iterator();
+        xFuncList->insert(nullptr, -1, &aCategory, nullptr, nullptr, nullptr, 
false,
+            mCategories[aCategory].get());
+    }
+    return mCategories[aCategory].get();
+}
+
 /*************************************************************************
 #*  Member:     UpdateLRUList
 #*------------------------------------------------------------------------
@@ -220,7 +250,10 @@ void ScFunctionWin::UpdateFunctionList(const OUString& 
rSearchString)
 
     xFuncList->clear();
     xFuncList->freeze();
+    mCategories.clear();
 
+    bool bCollapse = nCategory == 0;
+    bool bFilter = !rSearchString.isEmpty();
     if ( nSelPos > 0 )
     {
         ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
@@ -228,26 +261,40 @@ void ScFunctionWin::UpdateFunctionList(const OUString& 
rSearchString)
         SvtSysLocale aSysLocale;
         const CharClass& rCharClass = aSysLocale.GetCharClass();
         const OUString aSearchStr(rCharClass.uppercase(rSearchString));
+        const ScFuncDesc* pDesc = pFuncMgr->First(nCategory);
 
-        // First add the functions that start with the search string
-        const ScFuncDesc* pDesc = pFuncMgr->First( nCategory );
-        while ( pDesc )
+        while (pDesc)
         {
-            if (rSearchString.isEmpty()
-                || 
(rCharClass.uppercase(pDesc->getFunctionName()).startsWith(aSearchStr)))
-                xFuncList->append(weld::toId(pDesc), *(pDesc->mxFuncName));
+            OUString aCategory = pDesc->getCategory()->getName();
+            OUString aFunction = pDesc->getFunctionName();
+            OUString aFuncDescId = weld::toId(pDesc);
+
+            if (!bFilter || 
(rCharClass.uppercase(aFunction).startsWith(aSearchStr)))
+            {
+                weld::TreeIter* pCategory = FillCategoriesMap(aCategory, 
bCollapse);
+                xFuncList->insert(pCategory, -1, &aFunction, &aFuncDescId, 
nullptr, nullptr,
+                        false, xScratchIter.get());
+            }
             pDesc = pFuncMgr->Next();
         }
 
         // Now add the functions that have the search string in the middle of 
the function name
         // Note that this will only be necessary if the search string is not 
empty
-        if (!rSearchString.isEmpty())
+        if (bFilter)
         {
             pDesc = pFuncMgr->First( nCategory );
             while ( pDesc )
             {
-                if 
(rCharClass.uppercase(pDesc->getFunctionName()).indexOf(aSearchStr) > 0)
-                    xFuncList->append(weld::toId(pDesc), *(pDesc->mxFuncName));
+                OUString aCategory = pDesc->getCategory()->getName();
+                OUString aFunction = pDesc->getFunctionName();
+                OUString aFuncDescId = weld::toId(pDesc);
+
+                if (rCharClass.uppercase(aFunction).indexOf(aSearchStr) > 0)
+                {
+                    weld::TreeIter* pCategory = FillCategoriesMap(aCategory, 
bCollapse);
+                    xFuncList->insert(pCategory, -1, &aFunction, &aFuncDescId, 
nullptr, nullptr,
+                            false, xScratchIter.get());
+                }
                 pDesc = pFuncMgr->Next();
             }
         }
@@ -258,13 +305,23 @@ void ScFunctionWin::UpdateFunctionList(const OUString& 
rSearchString)
         {
             if (pDesc)
             {
-                xFuncList->append(weld::toId(pDesc), pDesc->getFunctionName());
+                OUString aFunction = pDesc->getFunctionName();
+                OUString aFuncDescId = weld::toId(pDesc);
+
+                xFuncList->insert(nullptr, -1, &aFunction, &aFuncDescId, 
nullptr, nullptr,
+                        false, xScratchIter.get());
             }
         }
     }
 
     xFuncList->thaw();
 
+    if (bCollapse && bFilter)
+    {
+        for (const auto& category : mCategories)
+            xFuncList->expand_row(*category.second);
+    }
+
     if (xFuncList->n_children() > 0)
     {
         xFuncList->set_sensitive(true);
@@ -285,16 +342,30 @@ void ScFunctionWin::UpdateFunctionList(const OUString& 
rSearchString)
 #*  Function:   Save input into document. Is called after clicking the
 #*              Apply button or a double-click on the function list.
 #*
-#*  Input:      ---
+#*  Input:      Boolean to know if I double-clicked/press-enter or not
 #*
 #*  Output:     ---
 #*
 #************************************************************************/
 
-void ScFunctionWin::DoEnter()
+void ScFunctionWin::DoEnter(bool bDoubleOrEnter)
 {
-    OUStringBuffer aArgStr;
     OUString aString=xFuncList->get_selected_text();
+    const bool isCategory = mCategories.find(aString) != mCategories.end();
+    if (isCategory && !bDoubleOrEnter)
+        return;
+
+    if (isCategory)
+    {
+        const auto& categoryRow = *(mCategories[aString]);
+        if (xFuncList->get_row_expanded(categoryRow))
+            xFuncList->collapse_row(categoryRow);
+        else
+            xFuncList->expand_row(categoryRow);
+        return;
+    }
+
+    OUStringBuffer aArgStr;
     SfxViewShell* pCurSh = SfxViewShell::Current();
     nArgs=0;
 
@@ -401,8 +472,6 @@ void ScFunctionWin::DoEnter()
 
 IMPL_LINK_NOARG(ScFunctionWin, ModifyHdl, weld::Entry&, void)
 {
-    // Switch to the "All" category when searching a function
-    xCatBox->set_active(1);
     OUString searchStr = m_xSearchString->get_text();
     UpdateFunctionList(searchStr);
     SetDescription();
@@ -426,7 +495,7 @@ IMPL_LINK(ScFunctionWin, KeyInputHdl, const KeyEvent&, 
rEvent, bool)
     {
     case KEY_RETURN:
         {
-            DoEnter();
+            DoEnter(true);
             bHandled = true;
         }
         break;
@@ -502,14 +571,17 @@ IMPL_LINK(ScFunctionWin, KeyInputHdl, const KeyEvent&, 
rEvent, bool)
 
 IMPL_LINK_NOARG(ScFunctionWin, SelComboHdl, weld::ComboBox&, void)
 {
-    UpdateFunctionList(u""_ustr);
+    xHelpButton->set_sensitive(xCatBox->get_active() != 1);
+    m_xSearchString->set_sensitive(xCatBox->get_active() > 0);
+    OUString searchStr = m_xSearchString->get_text();
+    UpdateFunctionList(searchStr);
     SetDescription();
-    m_xSearchString->set_text(u""_ustr);
-    m_xSearchString->grab_focus();
 }
 
 IMPL_LINK_NOARG(ScFunctionWin, SelTreeHdl, weld::TreeView&, void)
 {
+    bool bSensitivity = weld::fromId<const 
ScFuncDesc*>(xFuncList->get_selected_id());
+    xHelpButton->set_sensitive(bSensitivity);
     SetDescription();
 }
 
@@ -563,7 +635,7 @@ IMPL_LINK_NOARG( ScFunctionWin, SetHelpClickHdl, 
weld::Button&, void )
 
 IMPL_LINK_NOARG( ScFunctionWin, SetRowActivatedHdl, weld::TreeView&, bool )
 {
-    DoEnter();          // saves the input
+    DoEnter(true);      // saves the input
     return true;
 }
 
diff --git a/sc/source/ui/inc/dwfunctr.hxx b/sc/source/ui/inc/dwfunctr.hxx
index cc854fa317a1..e393f2a69fcb 100644
--- a/sc/source/ui/inc/dwfunctr.hxx
+++ b/sc/source/ui/inc/dwfunctr.hxx
@@ -20,6 +20,7 @@
 
 #include <comphelper/configurationlistener.hxx>
 #include <sfx2/sidebar/PanelLayout.hxx>
+#include <unordered_map>
 
 class ScFuncDesc;
 namespace formula { class IFunctionDescription; }
@@ -45,6 +46,7 @@ class ScFunctionWin : public PanelLayout
 private:
     std::unique_ptr<weld::ComboBox> xCatBox;
     std::unique_ptr<weld::TreeView> xFuncList;
+    std::unique_ptr<weld::TreeIter> xScratchIter;
     std::unique_ptr<weld::Button> xInsertButton;
     std::unique_ptr<weld::Button> xHelpButton;
     std::unique_ptr<weld::TextView> xFiFuncDesc;
@@ -58,10 +60,12 @@ private:
     OUString m_aSearchHelpId;
 
     ::std::vector< const formula::IFunctionDescription*> aLRUList;
+    ::std::unordered_map<OUString, std::unique_ptr<weld::TreeIter>> 
mCategories;
 
     void            UpdateLRUList();
-    void            DoEnter();
+    void            DoEnter(bool bDouble_or_Enter = false);
     void            SetDescription();
+    weld::TreeIter* FillCategoriesMap(const OUString&, bool);
 
                     DECL_LINK( SetRowActivatedHdl, weld::TreeView&, bool );
                     DECL_LINK( SetSelectionClickHdl, weld::Button&, void );
diff --git a/sc/uiconfig/scalc/ui/functionpanel.ui 
b/sc/uiconfig/scalc/ui/functionpanel.ui
index f67bd55a352d..671aa7149270 100644
--- a/sc/uiconfig/scalc/ui/functionpanel.ui
+++ b/sc/uiconfig/scalc/ui/functionpanel.ui
@@ -114,7 +114,7 @@
                     <property name="headers-visible">False</property>
                     <property name="headers-clickable">False</property>
                     <property name="search-column">0</property>
-                    <property name="show-expanders">False</property>
+                    <property name="show-expanders">True</property>
                     <child internal-child="selection">
                       <object class="GtkTreeSelection"/>
                     </child>

Reply via email to