formula/inc/bitmaps.hlst                                 |    2 
 formula/inc/strings.hrc                                  |    2 
 formula/source/ui/dlg/formula.cxx                        |   64 ++++++++++++---
 formula/source/ui/dlg/funcpage.cxx                       |   62 ++++++++++++--
 formula/source/ui/dlg/funcpage.hxx                       |   10 +-
 formula/uiconfig/ui/formuladialog.ui                     |   53 ++++++++++--
 formula/uiconfig/ui/functionpage.ui                      |    1 
 include/formula/IFunctionDescription.hxx                 |   12 ++
 officecfg/registry/schema/org/openoffice/Office/Calc.xcs |    7 +
 reportdesign/source/ui/dlg/Formula.cxx                   |    3 
 reportdesign/source/ui/inc/Formula.hxx                   |    1 
 reportdesign/source/ui/inc/FunctionHelper.hxx            |    3 
 reportdesign/source/ui/misc/FunctionHelper.cxx           |   14 +++
 sc/inc/appoptio.hxx                                      |    3 
 sc/inc/funcdesc.hxx                                      |   21 ++++
 sc/inc/scmod.hxx                                         |    1 
 sc/source/core/data/funcdesc.cxx                         |   15 +++
 sc/source/core/tool/appoptio.cxx                         |   29 ++++++
 sc/source/ui/app/scmod.cxx                               |   15 +++
 sc/source/ui/formdlg/dwfunctr.cxx                        |   42 +++++++--
 sc/source/ui/formdlg/formula.cxx                         |   10 ++
 sc/source/ui/inc/dwfunctr.hxx                            |    2 
 sc/source/ui/inc/formula.hxx                             |    1 
 sc/uiconfig/scalc/ui/functionpanel.ui                    |    1 
 24 files changed, 331 insertions(+), 43 deletions(-)

New commits:
commit dc77629b31423b4df553b7e63579f15445ddeab1
Author:     AhmedHamed <[email protected]>
AuthorDate: Tue Aug 13 17:12:45 2024 +0300
Commit:     Heiko Tietze <[email protected]>
CommitDate: Thu Jan 9 15:51:09 2025 +0100

    tdf#162286 Add a category to store favorite functions in FW
    
    Change-Id: Iec0d169570ba3d29501a4917d8858a9e9438f608
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171828
    Tested-by: Jenkins
    Reviewed-by: Heiko Tietze <[email protected]>

diff --git a/formula/inc/bitmaps.hlst b/formula/inc/bitmaps.hlst
index 259499f46f33..a99ff98f5acc 100644
--- a/formula/inc/bitmaps.hlst
+++ b/formula/inc/bitmaps.hlst
@@ -15,5 +15,7 @@ inline constexpr OUString BMP_STR_ERROR = 
u"formula/res/faperror.png"_ustr;
 inline constexpr OUString RID_BMP_REFBTN1 = u"formula/res/refinp1.png"_ustr;
 inline constexpr OUString RID_BMP_REFBTN2 = u"formula/res/refinp2.png"_ustr;
 inline constexpr OUString BMP_FX = u"formula/res/fx.png"_ustr;
+inline constexpr OUString BMP_STAR_EMPTY = 
u"sc/res/icon-set-stars-empty.png"_ustr;
+inline constexpr OUString BMP_STAR_FULL = 
u"sc/res/icon-set-stars-full.png"_ustr;
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/formula/inc/strings.hrc b/formula/inc/strings.hrc
index 63551e6deb25..cbb59c6a8efc 100644
--- a/formula/inc/strings.hrc
+++ b/formula/inc/strings.hrc
@@ -29,5 +29,7 @@
 #define STR_END             NC_("STR_END", "~End")
 #define RID_STR_SHRINK      NC_("RID_STR_SHRINK", "Shrink")
 #define RID_STR_EXPAND      NC_("RID_STR_EXPAND", "Expand")
+#define FAV_ENABLED         NC_("FAV_ENABLED", "Add or remove function from 
favourites")
+#define FAV_DISABLED        NC_("FAV_DISABLED", "Extention functions can not 
be added to favourites")
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/formula/source/ui/dlg/formula.cxx 
b/formula/source/ui/dlg/formula.cxx
index 1d1b3c6c624e..2fd606b89029 100644
--- a/formula/source/ui/dlg/formula.cxx
+++ b/formula/source/ui/dlg/formula.cxx
@@ -45,11 +45,13 @@
 #include <com/sun/star/sheet/FormulaMapGroupSpecialOffset.hpp>
 #include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
 #include <com/sun/star/sheet/XFormulaParser.hpp>
+#include <bitmaps.hlst>
 #include <map>
 
 // For tab page
 #define TOKEN_OPEN  0
 #define TOKEN_CLOSE 1
+
 namespace formula
 {
 
@@ -117,6 +119,7 @@ public:
     DECL_LINK( FormulaHdl, weld::TextView&, void);
     DECL_LINK( FormulaCursorHdl, weld::TextView&, void );
     DECL_LINK( BtnHdl, weld::Button&, void );
+    DECL_LINK( FavToggleHdl, weld::Button&, void );
     DECL_LINK( DblClkHdl, FuncPage&, void );
     DECL_LINK( FuncSelHdl, FuncPage&, void );
     DECL_LINK( StructSelHdl, StructPage&, void );
@@ -167,6 +170,8 @@ public:
     std::unique_ptr<weld::Label> m_xFtFuncName;
     std::unique_ptr<weld::Label> m_xFtFuncDesc;
 
+    std::unique_ptr<weld::Button> m_xBtnFavorites;
+
     std::unique_ptr<weld::Label> m_xFtEditName;
 
     std::unique_ptr<weld::Label> m_xFtResult;
@@ -230,6 +235,7 @@ FormulaDlg_Impl::FormulaDlg_Impl(weld::Dialog& rDialog,
     , m_xFtHeadLine(rBuilder.weld_label(u"headline"_ustr))
     , m_xFtFuncName(rBuilder.weld_label(u"funcname"_ustr))
     , m_xFtFuncDesc(rBuilder.weld_label(u"funcdesc"_ustr))
+    , m_xBtnFavorites(rBuilder.weld_button(u"favorites"_ustr))
     , m_xFtEditName(rBuilder.weld_label(u"editname"_ustr))
     , m_xFtResult(rBuilder.weld_label(u"label2"_ustr))
     , m_xWndResult(rBuilder.weld_entry(u"result"_ustr))
@@ -287,6 +293,9 @@ FormulaDlg_Impl::FormulaDlg_Impl(weld::Dialog& rDialog,
 
     m_aOldHelp = m_rDialog.get_help_id();                // HelpId from 
resource always for "Page 1"
 
+    m_xBtnFavorites->connect_clicked(LINK(this, FormulaDlg_Impl, 
FavToggleHdl));
+    m_xBtnFavorites->hide();
+
     m_xFtResult->set_visible( _bSupportResult );
     m_xWndResult->set_visible( _bSupportResult );
 
@@ -863,6 +872,7 @@ void FormulaDlg_Impl::FillControls( bool &rbNext, bool 
&rbPrev)
         const bool bTestFlag = (pOldFuncDesc != m_pFuncDesc);
         if (bTestFlag)
         {
+            m_xBtnFavorites->hide();
             m_xFtHeadLine->hide();
             m_xFtFuncName->hide();
             m_xFtFuncDesc->hide();
@@ -965,6 +975,7 @@ void FormulaDlg_Impl::ClearAllParas()
         m_xParaWinBox->hide();
 
         m_xBtnForward->set_sensitive(true); //@new
+        m_xBtnFavorites->show();
         m_xFtHeadLine->show();
         m_xFtFuncName->show();
         m_xFtFuncDesc->show();
@@ -1058,6 +1069,27 @@ IMPL_LINK(FormulaDlg_Impl, BtnHdl, weld::Button&, rBtn, 
void)
     }
 }
 
+IMPL_LINK_NOARG(FormulaDlg_Impl, FavToggleHdl, weld::Button&, void)
+{
+    const IFunctionDescription* pDesc = m_xFuncPage->GetFuncDesc();
+    if (!pDesc)
+        return;
+
+    if (m_xFuncPage->IsFavourite(m_xFuncPage->GetFuncIndex()))
+    {
+        m_pHelper->insertOrEraseFavouritesListEntry(pDesc, false);
+        m_xBtnFavorites->set_from_icon_name(BMP_STAR_EMPTY);
+    }
+    else
+    {
+        m_pHelper->insertOrEraseFavouritesListEntry(pDesc, true);
+        m_xBtnFavorites->set_from_icon_name(BMP_STAR_FULL);
+    }
+    m_xFuncPage->UpdateFavouritesList();
+    if (m_xFuncPage->GetCategory() == FAVOURITES_CATEGORY)
+        m_xFuncPage->UpdateFunctionList(u""_ustr);
+}
+
 //                          Functions for 1. Page
 
 // Handler for Listboxes
@@ -1667,23 +1699,25 @@ IMPL_LINK_NOARG( FormulaDlg_Impl, MatrixHdl, 
weld::Toggleable&, void)
 
 IMPL_LINK_NOARG( FormulaDlg_Impl, FuncSelHdl, FuncPage&, void)
 {
-    if (   (m_xFuncPage->GetFunctionEntryCount() > 0)
-        && (m_xFuncPage->GetFunction() != -1) )
-    {
-        const IFunctionDescription* pDesc = m_xFuncPage->GetFuncDesc();
+    const IFunctionDescription* pDesc = m_xFuncPage->GetFuncDesc();
+    const sal_uInt16 nFIndex = m_xFuncPage->GetFuncIndex();
 
+    m_xBtnFavorites->set_sensitive(true);
+    if (pDesc)
+    {
         if (pDesc != m_pFuncDesc)
             m_xBtnForward->set_sensitive(true); //new
 
-        if (pDesc)
-        {
-            pDesc->initArgumentInfo();      // full argument info is needed
+        pDesc->initArgumentInfo();      // full argument info is needed
+        OUString aSig = pDesc->getSignature();
+        m_xFtHeadLine->set_label( pDesc->getFunctionName() );
+        m_xFtFuncName->set_label( aSig );
+        m_xFtFuncDesc->set_label( pDesc->getDescription() );
 
-            OUString aSig = pDesc->getSignature();
-            m_xFtHeadLine->set_label( pDesc->getFunctionName() );
-            m_xFtFuncName->set_label( aSig );
-            m_xFtFuncDesc->set_label( pDesc->getDescription() );
-        }
+        if (m_xFuncPage->IsFavourite(nFIndex))
+            m_xBtnFavorites->set_from_icon_name(BMP_STAR_FULL);
+        else
+            m_xBtnFavorites->set_from_icon_name(BMP_STAR_EMPTY);
     }
     else
     {
@@ -1691,6 +1725,12 @@ IMPL_LINK_NOARG( FormulaDlg_Impl, FuncSelHdl, FuncPage&, 
void)
         m_xFtFuncName->set_label( OUString() );
         m_xFtFuncDesc->set_label( OUString() );
     }
+
+    m_xBtnFavorites->set_visible(m_xFtHeadLine->is_visible()
+                                 && m_xFtHeadLine->get_label() != u""_ustr);
+    m_xBtnFavorites->set_sensitive(nFIndex != 0);
+    m_xBtnFavorites->set_tooltip_text(nFIndex == 0 ? ForResId(FAV_DISABLED)
+                                                   : ForResId(FAV_ENABLED));
 }
 
 void FormulaDlg_Impl::UpdateParaWin( const Selection& _rSelection, const 
OUString& _sRefStr)
diff --git a/formula/source/ui/dlg/funcpage.cxx 
b/formula/source/ui/dlg/funcpage.cxx
index 60d1e5adf2a0..315899926680 100644
--- a/formula/source/ui/dlg/funcpage.cxx
+++ b/formula/source/ui/dlg/funcpage.cxx
@@ -40,7 +40,7 @@ IMPL_LINK(FuncPage, KeyInputHdl, const KeyEvent&, rKEvt, bool)
 }
 
 // tdf#104487 - remember last used function category - set default to All 
category
-sal_Int32 FuncPage::m_nRememberedFunctionCategory = 1;
+sal_Int32 FuncPage::m_nRememberedFunctionCategory = ALL_CATEGORY;
 
 FuncPage::FuncPage(weld::Container* pParent, const IFunctionManager* 
_pFunctionManager)
     : m_xBuilder(Application::CreateBuilder(pParent, 
u"formula/ui/functionpage.ui"_ustr))
@@ -56,6 +56,7 @@ FuncPage::FuncPage(weld::Container* pParent, const 
IFunctionManager* _pFunctionM
     m_aHelpId = m_xLbFunction->get_help_id();
 
     m_pFunctionManager->fillLastRecentlyUsedFunctions(aLRUList);
+    m_pFunctionManager->fillFavouriteFunctions(aFavouritesList);
 
     const sal_uInt32 nCategoryCount = m_pFunctionManager->getCount();
     for (sal_uInt32 j = 0; j < nCategoryCount; ++j)
@@ -100,6 +101,24 @@ weld::TreeIter* FuncPage::FillCategoriesMap(const 
OUString& aCategory, bool bFil
     return mCategories[aCategory].get();
 }
 
+bool FuncPage::IsFavourite(sal_uInt16 nFIndex) const
+{
+    return aFavouritesList.find(nFIndex) != aFavouritesList.end();
+}
+
+bool FuncPage::UpdateFavouritesList()
+{
+    sal_uInt16 nFIndex = GetFuncIndex();
+    if (nFIndex == 0)
+        return false;
+
+    if (IsFavourite(nFIndex))
+        aFavouritesList.erase(nFIndex);
+    else
+        aFavouritesList.insert(nFIndex);
+    return true;
+}
+
 void FuncPage::impl_addFunctions(const IFunctionCategory* _pCategory, bool 
bFillCategories)
 {
     weld::TreeIter* pCategoryIter = FillCategoriesMap(_pCategory->getName(), 
bFillCategories);
@@ -141,17 +160,17 @@ void FuncPage::UpdateFunctionList(const OUString& aStr)
     sFuncScores.clear();
 
     const sal_Int32 nSelPos = m_xLbCategory->get_active();
-    bool bCollapse = nSelPos == 1;
+    bool bCollapse = nSelPos == ALL_CATEGORY;
     bool bFilter = !aStr.isEmpty();
     // tdf#104487 - remember last used function category
     m_nRememberedFunctionCategory = nSelPos;
 
-    if (!bFilter || nSelPos == 0)
+    if (!bFilter || nSelPos == LRU_CATEGORY || nSelPos == FAVOURITES_CATEGORY)
     {
         const IFunctionCategory* pCategory
             = weld::fromId<const 
IFunctionCategory*>(m_xLbCategory->get_id(nSelPos));
 
-        if (nSelPos > 0)
+        if (nSelPos >= ALL_CATEGORY)
         {
             if (pCategory == nullptr)
             {
@@ -166,7 +185,7 @@ void FuncPage::UpdateFunctionList(const OUString& aStr)
                 impl_addFunctions(pCategory, false);
             }
         }
-        else // LRU-List
+        else if (nSelPos == LRU_CATEGORY) // LRU-List
         {
             for (auto const& elem : aLRUList)
             {
@@ -180,6 +199,24 @@ void FuncPage::UpdateFunctionList(const OUString& aStr)
                 }
             }
         }
+        else // Favourites-List
+        {
+            for (const auto& elem : aFavouritesList)
+            {
+                if (m_pFunctionManager->Get(elem))
+                {
+                    TFunctionDesc pDesc(m_pFunctionManager->Get(elem));
+                    if (pDesc && !pDesc->isHidden())
+                    {
+                        OUString aFunction(pDesc->getFunctionName());
+                        OUString sId(weld::toId(pDesc));
+
+                        m_xLbFunction->insert(nullptr, -1, &aFunction, &sId, 
nullptr, nullptr,
+                                              false, m_xScratchIter.get());
+                    }
+                }
+            }
+        }
     }
     else
     {
@@ -249,11 +286,12 @@ void FuncPage::UpdateFunctionList(const OUString& aStr)
 
 IMPL_LINK_NOARG(FuncPage, SelComboBoxHdl, weld::ComboBox&, void)
 {
-    if (m_xLbCategory->get_active() == 0)
+    if (m_xLbCategory->get_active() == LRU_CATEGORY
+        || m_xLbCategory->get_active() == FAVOURITES_CATEGORY)
         m_xLbFunctionSearchString->set_text(u""_ustr);
     m_xHelpButton->set_sensitive(false);
-    OUString searchStr = m_xLbFunctionSearchString->get_text();
     m_xLbFunction->set_help_id(m_aHelpId);
+    OUString searchStr = m_xLbFunctionSearchString->get_text();
     UpdateFunctionList(searchStr);
 }
 
@@ -290,9 +328,10 @@ IMPL_LINK_NOARG(FuncPage, DblClkHdl, weld::TreeView&, bool)
 
 IMPL_LINK_NOARG(FuncPage, ModifyHdl, weld::Entry&, void)
 {
-    if (m_xLbCategory->get_active() == 0)
+    if (m_xLbCategory->get_active() == LRU_CATEGORY
+        || m_xLbCategory->get_active() == FAVOURITES_CATEGORY)
     {
-        m_xLbCategory->set_active(1);
+        m_xLbCategory->set_active(ALL_CATEGORY);
         m_xHelpButton->set_sensitive(false);
     }
     OUString searchStr = m_xLbFunctionSearchString->get_text();
@@ -354,6 +393,11 @@ sal_Int32 FuncPage::GetFunctionEntryCount() const { return 
m_xLbFunction->n_chil
 
 OUString FuncPage::GetSelFunctionName() const { return 
m_xLbFunction->get_selected_text(); }
 
+sal_uInt16 FuncPage::GetFuncIndex() const
+{
+    return m_pFunctionManager->getFunctionIndex(GetFuncDesc());
+}
+
 const IFunctionDescription* FuncPage::GetFuncDesc() const
 {
     if (GetFunction() == -1)
diff --git a/formula/source/ui/dlg/funcpage.hxx 
b/formula/source/ui/dlg/funcpage.hxx
index 010bca872832..9fcd1c0b02c6 100644
--- a/formula/source/ui/dlg/funcpage.hxx
+++ b/formula/source/ui/dlg/funcpage.hxx
@@ -23,6 +23,7 @@
 #include <vector>
 #include <set>
 #include <unordered_map>
+#include <unordered_set>
 
 namespace formula
 {
@@ -51,6 +52,7 @@ private:
     const IFunctionManager*  m_pFunctionManager;
 
     ::std::vector< TFunctionDesc >  aLRUList;
+    ::std::unordered_set<sal_uInt16> aFavouritesList;
     ::std::unordered_map<OUString, std::unique_ptr<weld::TreeIter>> 
mCategories;
     ::std::set<std::pair<std::pair<sal_Int32, sal_Int32>, std::pair<OUString, 
TFunctionDesc>>>
         sFuncScores;
@@ -70,8 +72,6 @@ private:
     DECL_LINK(SelHelpClickHdl, weld::Button&, void);
     DECL_LINK(SimilarityToggleHdl, weld::Toggleable&, void);
 
-    void            UpdateFunctionList(const OUString&);
-
 public:
 
     FuncPage(weld::Container* pContainer, const IFunctionManager* 
_pFunctionManager);
@@ -91,6 +91,7 @@ public:
     sal_Int32       GetFuncPos(const IFunctionDescription* _pDesc);
     const IFunctionDescription* GetFuncDesc() const;
     OUString        GetSelFunctionName() const;
+    sal_uInt16      GetFuncIndex() const;
 
     void            SetDoubleClickHdl( const Link<FuncPage&,void>& rLink ) { 
aDoubleClickLink = rLink; }
 
@@ -98,6 +99,11 @@ public:
 
     bool            IsVisible() const { return m_xContainer->get_visible(); }
 
+    bool            IsFavourite(sal_uInt16) const;
+
+    bool            UpdateFavouritesList();
+    void            UpdateFunctionList(const OUString&);
+
     void            SearchFunction(const OUString&, const OUString&, 
TFunctionDesc, const bool);
 };
 
diff --git a/formula/uiconfig/ui/formuladialog.ui 
b/formula/uiconfig/ui/formuladialog.ui
index 1bb11eefe9ba..d43ec78daa6c 100644
--- a/formula/uiconfig/ui/formuladialog.ui
+++ b/formula/uiconfig/ui/formuladialog.ui
@@ -183,7 +183,7 @@
                   </object>
                   <packing>
                     <property name="resize">False</property>
-                    <property name="shrink">True</property>
+                    <property name="shrink">False</property>
                   </packing>
                 </child>
                 <child>
@@ -285,18 +285,55 @@
                         <property name="vexpand">True</property>
                         <property name="row-spacing">12</property>
                         <child>
-                          <object class="GtkLabel" id="headline">
+                          <object class="GtkBox">
                             <property name="visible">True</property>
                             <property name="can-focus">False</property>
                             <property name="hexpand">True</property>
-                            <property name="wrap">True</property>
-                            <property name="xalign">0</property>
-                            <property name="yalign">0</property>
-                            <attributes>
-                              <attribute name="weight" value="bold"/>
-                            </attributes>
+                            <property name="vexpand">False</property>
+                            <property name="orientation">horizontal</property>
+                            <property name="spacing">2</property>
+                            <child>
+                              <object class="GtkButton" id="favorites">
+                                <property name="visible">True</property>
+                                <property name="can-focus">True</property>
+                                <property 
name="receives-default">True</property>
+                                <property name="tooltip-text" 
translatable="yes" context="formuladialog|favorites|tooltip_text">Add or remove 
function from favourites</property>
+                                <property name="hexpand">False</property>
+                                <property name="vexpand">False</property>
+                                <property name="halign">start</property>
+                                <property name="valign">center</property>
+                                <property name="relief">none</property>
+                                <property name="border-width">6</property>
+                                <property 
name="focus-on-click">False</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="headline">
+                                <property name="visible">True</property>
+                                <property name="can-focus">False</property>
+                                <property name="hexpand">True</property>
+                                <property name="wrap">True</property>
+                                <property name="xalign">0</property>
+                                <property name="yalign">0.5</property>
+                                <attributes>
+                                  <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
                           </object>
                           <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
                             <property name="left-attach">0</property>
                             <property name="top-attach">0</property>
                           </packing>
diff --git a/formula/uiconfig/ui/functionpage.ui 
b/formula/uiconfig/ui/functionpage.ui
index c48beb6918ac..c867539ce6e9 100644
--- a/formula/uiconfig/ui/functionpage.ui
+++ b/formula/uiconfig/ui/functionpage.ui
@@ -93,6 +93,7 @@
         <property name="can-focus">False</property>
         <items>
           <item translatable="yes" context="functionpage|category">Last 
Used</item>
+          <item translatable="yes" 
context="functionpage|category">Favourites</item>
           <item translatable="yes" context="functionpage|category">All</item>
         </items>
         <child internal-child="accessible">
diff --git a/include/formula/IFunctionDescription.hxx 
b/include/formula/IFunctionDescription.hxx
index d511089a274b..70a4ca052f35 100644
--- a/include/formula/IFunctionDescription.hxx
+++ b/include/formula/IFunctionDescription.hxx
@@ -22,12 +22,18 @@
 
 #include <memory>
 #include <vector>
+#include <unordered_set>
+#include <unordered_map>
 
 #include <com/sun/star/table/CellAddress.hpp>
 #include <com/sun/star/uno/Reference.hxx>
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
 
+#define LRU_CATEGORY 0
+#define FAVOURITES_CATEGORY 1
+#define ALL_CATEGORY 2
+
 namespace com::sun::star {
     namespace sheet { struct FormulaToken; }
     namespace sheet { class XFormulaOpCodeMapper; }
@@ -57,13 +63,18 @@ namespace formula
             eTableRefOpen,
             eTableRefClose
         };
+
+        virtual const IFunctionDescription* Get(sal_uInt16 nFIndex) const = 0;
         virtual sal_uInt32 getCount() const = 0;
         virtual const IFunctionCategory* getCategory(sal_uInt32 nPos) const = 
0;
+        virtual sal_uInt16 getFunctionIndex(const IFunctionDescription* 
_pDesc) const = 0;
         virtual void fillLastRecentlyUsedFunctions(::std::vector< const 
IFunctionDescription*>& _rLastRUFunctions) const = 0;
+        virtual void fillFavouriteFunctions(::std::unordered_set<sal_uInt16>& 
rFavouriteFunctions) const = 0;
 
         virtual sal_Unicode getSingleToken(const EToken _eToken) const = 0;
 
     protected:
+        bool changeFavouriteList;
         ~IFunctionManager() {}
     };
 
@@ -150,6 +161,7 @@ namespace formula
         virtual void dispatch(bool _bOK, bool _bMatrixChecked) = 0;
         virtual void doClose(bool _bOk) = 0;
         virtual void insertEntryToLRUList(const IFunctionDescription*   pDesc) 
= 0;
+        virtual void insertOrEraseFavouritesListEntry(const 
IFunctionDescription* pDesc, bool bInsert) = 0;
         virtual void showReference(const OUString& _sFormula) = 0;
 
     protected:
diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
index 22e14c4421fe..854b480bc424 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
@@ -762,6 +762,13 @@
         </constraints>
         <value>224 226 222 223 6</value>
       </prop>
+      <prop oor:name="FavouriteFunctions" oor:type="oor:int-list" 
oor:nillable="false">
+        <info>
+          <desc>Specifies the favourite functions.</desc>
+          <label>Favourite Functions</label>
+        </info>
+        <value></value>
+      </prop>
       <prop oor:name="AutoInput" oor:type="xs:boolean" oor:nillable="false">
         <!-- UIHints: Tools  Cell Contents  AutoInput -->
         <info>
diff --git a/reportdesign/source/ui/dlg/Formula.cxx 
b/reportdesign/source/ui/dlg/Formula.cxx
index ec1fc754549b..83a358d5495d 100644
--- a/reportdesign/source/ui/dlg/Formula.cxx
+++ b/reportdesign/source/ui/dlg/Formula.cxx
@@ -126,6 +126,9 @@ void FormulaDialog::doClose(bool _bOk)
 void FormulaDialog::insertEntryToLRUList(const IFunctionDescription*    
/*_pDesc*/)
 {
 }
+void FormulaDialog::insertOrEraseFavouritesListEntry(const 
IFunctionDescription* /*_pDesc*/, bool)
+{
+}
 void FormulaDialog::showReference(const OUString& /*_sFormula*/)
 {
 }
diff --git a/reportdesign/source/ui/inc/Formula.hxx 
b/reportdesign/source/ui/inc/Formula.hxx
index 9271d68e5a15..48d163e1a054 100644
--- a/reportdesign/source/ui/inc/Formula.hxx
+++ b/reportdesign/source/ui/inc/Formula.hxx
@@ -77,6 +77,7 @@ public:
     virtual std::unique_ptr<formula::FormulaCompiler> createCompiler( 
formula::FormulaTokenArray& rArray ) const override;
     virtual void doClose(bool _bOk) override;
     virtual void insertEntryToLRUList(const formula::IFunctionDescription*  
pDesc) override;
+    virtual void insertOrEraseFavouritesListEntry(const 
formula::IFunctionDescription*  pDesc, bool bInsert) override;
     virtual void showReference(const OUString& _sFormula) override;
     virtual void dispatch(bool _bOK, bool _bMatrixChecked) override;
     virtual void setDispatcherLock( bool bLock ) override;
diff --git a/reportdesign/source/ui/inc/FunctionHelper.hxx 
b/reportdesign/source/ui/inc/FunctionHelper.hxx
index 2d9fbed18cbd..7288d99df6e0 100644
--- a/reportdesign/source/ui/inc/FunctionHelper.hxx
+++ b/reportdesign/source/ui/inc/FunctionHelper.hxx
@@ -45,9 +45,12 @@ class FunctionManager : public formula::IFunctionManager
 public:
             FunctionManager(css::uno::Reference< 
css::report::meta::XFunctionManager> _xMgr);
     virtual ~FunctionManager();
+    virtual const formula::IFunctionDescription*    Get(sal_uInt16 nFIndex) 
const override;
     virtual sal_uInt32                              getCount() const override;
     virtual const formula::IFunctionCategory*       getCategory(sal_uInt32 
nPos) const override;
+    virtual sal_uInt16                              getFunctionIndex(const 
formula::IFunctionDescription* _pDesc) const override;
     virtual void                                    
fillLastRecentlyUsedFunctions(::std::vector< const 
formula::IFunctionDescription*>& _rLastRUFunctions) const override;
+    virtual void                                    
fillFavouriteFunctions(::std::unordered_set<sal_uInt16>& rFavouriteFunctions) 
const override;
     virtual sal_Unicode                             getSingleToken(const 
EToken _eToken) const override;
 
     std::shared_ptr< FunctionDescription >      get(const css::uno::Reference< 
css::report::meta::XFunctionDescription>& _xFunctionDescription) const;
diff --git a/reportdesign/source/ui/misc/FunctionHelper.cxx 
b/reportdesign/source/ui/misc/FunctionHelper.cxx
index ec3a2650cb33..e4ec31aad8e2 100644
--- a/reportdesign/source/ui/misc/FunctionHelper.cxx
+++ b/reportdesign/source/ui/misc/FunctionHelper.cxx
@@ -59,6 +59,11 @@ sal_Unicode FunctionManager::getSingleToken(const 
formula::IFunctionManager::ETo
     return 0;
 }
 
+const formula::IFunctionDescription* FunctionManager::Get(sal_uInt16 
/*nFIndex*/) const
+{
+    return nullptr;
+}
+
 sal_uInt32 FunctionManager::getCount() const
 {
     return m_xMgr->getCount();
@@ -75,10 +80,19 @@ const formula::IFunctionCategory* 
FunctionManager::getCategory(sal_uInt32 _nPos)
     return m_aCategoryIndex[_nPos]->second.get();
 }
 
+sal_uInt16 FunctionManager::getFunctionIndex(const 
formula::IFunctionDescription* /*_pDesc*/) const
+{
+    return 0;
+}
+
 void FunctionManager::fillLastRecentlyUsedFunctions(::std::vector< const 
formula::IFunctionDescription*>& /*_rLastRUFunctions*/) const
 {
 }
 
+void FunctionManager::fillFavouriteFunctions(::std::unordered_set<sal_uInt16>& 
/*rFavouriteFunctions*/) const
+{
+}
+
 std::shared_ptr< FunctionDescription > FunctionManager::get(const 
uno::Reference< report::meta::XFunctionDescription>& _xFunctionDescription) 
const
 {
     std::shared_ptr< FunctionDescription > pDesc;
diff --git a/sc/inc/appoptio.hxx b/sc/inc/appoptio.hxx
index d9e22c9cba78..af637c5dbdef 100644
--- a/sc/inc/appoptio.hxx
+++ b/sc/inc/appoptio.hxx
@@ -48,6 +48,8 @@ public:
     sal_uInt16* GetLRUFuncList() const          { return pLRUList.get();      }
     void        SetLRUFuncList( const sal_uInt16* pList,
                                 const sal_uInt16  nCount );
+    std::unordered_set<sal_uInt16> GetFavouritesList() const { return 
sFavouritesList; }
+    void        SetFavouritesList(const std::unordered_set<sal_uInt16>& rList) 
{ sFavouritesList = rList; }
     void        SetStatusFunc( sal_uInt32 nNew )    { nStatusFunc = nNew;   }
     sal_uInt32      GetStatusFunc() const           { return nStatusFunc;   }
     void        SetAutoComplete( bool bNew )    { bAutoComplete = bNew; }
@@ -87,6 +89,7 @@ private:
     sal_uInt16      nLRUFuncCount;
     std::unique_ptr<sal_uInt16[]>
                     pLRUList;
+    std::unordered_set<sal_uInt16> sFavouritesList;
     SvxZoomType     eZoomType;
     sal_uInt16      nZoom;
     bool            bSynchronizeZoom;
diff --git a/sc/inc/funcdesc.hxx b/sc/inc/funcdesc.hxx
index 49b718dbd1ae..21026a401828 100644
--- a/sc/inc/funcdesc.hxx
+++ b/sc/inc/funcdesc.hxx
@@ -28,6 +28,7 @@
 #include <rtl/ustring.hxx>
 #include <optional>
 #include <map>
+#include <unordered_set>
 #include <memory>
 
 #define MAX_FUNCCAT 12  /* maximum number of categories for functions */
@@ -336,7 +337,7 @@ public:
 
       @return pointer to function with the index nFIndex, null if no such 
function was found.
     */
-    const ScFuncDesc* Get( sal_uInt16 nFIndex ) const;
+    const formula::IFunctionDescription* Get( sal_uInt16 nFIndex ) const 
override;
 
     /**
       Returns the first function in category nCategory.
@@ -374,6 +375,16 @@ public:
     */
     virtual const formula::IFunctionCategory* getCategory(sal_uInt32 nPos) 
const override;
 
+    /**
+      Returns the index of the function.
+
+      @param _pDesc
+      Pointer to function description
+
+      @return The index of the function if not null, 0 otherwise.
+    */
+    virtual sal_uInt16 getFunctionIndex(const formula::IFunctionDescription* 
_pDesc) const override;
+
     /**
       Appends the last recently used functions.
 
@@ -384,6 +395,14 @@ public:
     */
     virtual void fillLastRecentlyUsedFunctions(::std::vector< const 
formula::IFunctionDescription*>& _rLastRUFunctions) const override;
 
+    /**
+      Appends favourite functions to the given vector.
+
+      @param rFavouriteFunctions
+      a vector of pointer to IFunctionDescription, by reference.
+    */
+    virtual void fillFavouriteFunctions(std::unordered_set<sal_uInt16>& 
rFavouriteFunctions) const override;
+
     /**
       Maps Etoken to character
 
diff --git a/sc/inc/scmod.hxx b/sc/inc/scmod.hxx
index 3811a9334fa6..fd19d67df5d9 100644
--- a/sc/inc/scmod.hxx
+++ b/sc/inc/scmod.hxx
@@ -173,6 +173,7 @@ public:
     SC_DLLPUBLIC void   SetInputOptions ( const ScInputOptions& rOpt );
     void                SetPrintOptions ( const ScPrintOptions& rOpt );
     void                InsertEntryToLRUList(sal_uInt16 nFIndex);
+    void                InsertOrEraseFavouritesListEntry(sal_uInt16 nFIndex, 
bool bInsert);
 
     static void         GetSpellSettings( LanguageType& rDefLang, 
LanguageType& rCjkLang, LanguageType& rCtlLang );
     static void         SetAutoSpellProperty( bool bSet );
diff --git a/sc/source/core/data/funcdesc.cxx b/sc/source/core/data/funcdesc.cxx
index 6ca1b262792c..f3eae4ea07ab 100644
--- a/sc/source/core/data/funcdesc.cxx
+++ b/sc/source/core/data/funcdesc.cxx
@@ -1081,7 +1081,7 @@ ScFunctionMgr::~ScFunctionMgr()
 }
 
 
-const ScFuncDesc* ScFunctionMgr::Get( sal_uInt16 nFIndex ) const
+const formula::IFunctionDescription* ScFunctionMgr::Get( sal_uInt16 nFIndex ) 
const
 {
     const ScFuncDesc* pDesc;
     for (pDesc = First(); pDesc; pDesc = Next())
@@ -1137,6 +1137,12 @@ const formula::IFunctionCategory* 
ScFunctionMgr::getCategory(sal_uInt32 nCategor
     return nullptr;
 }
 
+sal_uInt16 ScFunctionMgr::getFunctionIndex(const 
formula::IFunctionDescription* _pDesc) const
+{
+    const ScFuncDesc* pDesc = dynamic_cast<const ScFuncDesc*>(_pDesc);
+    return pDesc ? pDesc->nFIndex : 0;
+}
+
 void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const 
formula::IFunctionDescription*>& _rLastRUFunctions) const
 {
     const ScAppOptions& rAppOpt = ScModule::get()->GetAppOptions();
@@ -1153,6 +1159,13 @@ void 
ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const formula::
     }
 }
 
+void ScFunctionMgr::fillFavouriteFunctions(std::unordered_set<sal_uInt16>& 
rFavouriteFunctions) const
+{
+    const ScAppOptions& rAppOpt = ScModule::get()->GetAppOptions();
+    rFavouriteFunctions.clear();
+    rFavouriteFunctions = rAppOpt.GetFavouritesList();
+}
+
 OUString ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber )
 {
     if (_nCategoryNumber >= SC_FUNCGROUP_COUNT)
diff --git a/sc/source/core/tool/appoptio.cxx b/sc/source/core/tool/appoptio.cxx
index 0115be53db76..e6137341094d 100644
--- a/sc/source/core/tool/appoptio.cxx
+++ b/sc/source/core/tool/appoptio.cxx
@@ -26,6 +26,7 @@
 #include <miscuno.hxx>
 #include <vector>
 #include <osl/diagnose.h>
+#include <comphelper/sequence.hxx>
 
 using namespace utl;
 using namespace com::sun::star::uno;
@@ -90,6 +91,7 @@ ScAppOptions& ScAppOptions::operator=( const ScAppOptions& 
rCpy )
     bSynchronizeZoom = rCpy.bSynchronizeZoom;
     nZoom           = rCpy.nZoom;
     SetLRUFuncList( rCpy.pLRUList.get(), rCpy.nLRUFuncCount );
+    SetFavouritesList(rCpy.sFavouritesList);
     nStatusFunc     = rCpy.nStatusFunc;
     bAutoComplete   = rCpy.bAutoComplete;
     bDetectiveAuto  = rCpy.bDetectiveAuto;
@@ -139,6 +141,11 @@ static void lcl_GetLastFunctions( Any& rDest, const 
ScAppOptions& rOpt )
         rDest <<= Sequence<sal_Int32>(0);   // empty
 }
 
+static void lcl_GetFavouriteFunctions(Any& rDest, const ScAppOptions& rOpt)
+{
+    rDest <<= 
comphelper::containerToSequence<sal_Int32>(rOpt.GetFavouritesList());
+}
+
 static void lcl_GetSortList( Any& rDest )
 {
     const ScUserList& rUserList = ScGlobal::GetUserList();
@@ -162,8 +169,9 @@ constexpr OUStringLiteral CFGPATH_LAYOUT = 
u"Office.Calc/Layout";
 constexpr OUStringLiteral CFGPATH_INPUT = u"Office.Calc/Input";
 
 #define SCINPUTOPT_LASTFUNCS        0
-#define SCINPUTOPT_AUTOINPUT        1
-#define SCINPUTOPT_DET_AUTO         2
+#define SCINPUTOPT_FAVOURITEFUNCS   1
+#define SCINPUTOPT_AUTOINPUT        2
+#define SCINPUTOPT_DET_AUTO         3
 
 constexpr OUStringLiteral CFGPATH_REVISION = u"Office.Calc/Revision/Color";
 
@@ -225,6 +233,7 @@ Sequence<OUString> ScAppCfg::GetLayoutPropertyNames()
 Sequence<OUString> ScAppCfg::GetInputPropertyNames()
 {
     return {u"LastFunctions"_ustr,            // SCINPUTOPT_LASTFUNCS
+            u"FavouriteFunctions"_ustr,       // SCINPUTOPT_FAVOURITEFUNCS
             u"AutoInput"_ustr,                // SCINPUTOPT_AUTOINPUT
             u"DetectiveAuto"_ustr};           // SCINPUTOPT_DET_AUTO
 }
@@ -363,6 +372,19 @@ void ScAppCfg::ReadInputCfg()
             SetLRUFuncList(pUShorts.data(), nLRUCount);
         }
     }
+
+    if (Sequence<sal_Int32> aSeq; aValues[SCINPUTOPT_FAVOURITEFUNCS] >>= aSeq)
+    {
+        sal_Int32 nCount = aSeq.getLength();
+        if (nCount < SAL_MAX_UINT16)
+        {
+            sal_uInt16 nFavouritesCount = nCount;
+            std::unordered_set<sal_uInt16> sFavouriteFunctions;
+            for (sal_uInt16 i = 0; i < nFavouritesCount; ++i)
+                sFavouriteFunctions.insert(aSeq[i]);
+            SetFavouritesList(sFavouriteFunctions);
+        }
+    }
     
SetAutoComplete(ScUnoHelpFunctions::GetBoolFromAny(aValues[SCINPUTOPT_AUTOINPUT]));
     
SetDetectiveAuto(ScUnoHelpFunctions::GetBoolFromAny(aValues[SCINPUTOPT_DET_AUTO]));
 }
@@ -515,6 +537,9 @@ IMPL_LINK_NOARG(ScAppCfg, InputCommitHdl, 
ScLinkConfigItem&, void)
             case SCINPUTOPT_DET_AUTO:
                 pValues[nProp] <<= GetDetectiveAuto();
                 break;
+            case SCINPUTOPT_FAVOURITEFUNCS:
+                lcl_GetFavouriteFunctions(pValues[nProp], *this);
+                break;
         }
     }
     aInputItem.PutProperties(aNames, aValues);
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index e5f940bbbe34..84238486fa6b 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -785,6 +785,21 @@ void ScModule::InsertEntryToLRUList(sal_uInt16 nFIndex)
     SetAppOptions(aNewOpts);
 }
 
+void ScModule::InsertOrEraseFavouritesListEntry(sal_uInt16 nFIndex, bool 
bInsert)
+{
+    const ScAppOptions& rAppOpt = GetAppOptions();
+    std::unordered_set<sal_uInt16> sFavouriteFunctions = 
rAppOpt.GetFavouritesList();
+
+    if (bInsert)
+        sFavouriteFunctions.insert(nFIndex);
+    else
+        sFavouriteFunctions.erase(nFIndex);
+
+    ScAppOptions aNewOpts(rAppOpt);
+    aNewOpts.SetFavouritesList(sFavouriteFunctions);
+    SetAppOptions(aNewOpts);
+}
+
 void ScModule::SetAppOptions( const ScAppOptions& rOpt )
 {
     if ( !m_pAppCfg )
diff --git a/sc/source/ui/formdlg/dwfunctr.cxx 
b/sc/source/ui/formdlg/dwfunctr.cxx
index 3345e1f83f95..e46a4edd582c 100644
--- a/sc/source/ui/formdlg/dwfunctr.cxx
+++ b/sc/source/ui/formdlg/dwfunctr.cxx
@@ -64,6 +64,7 @@ ScFunctionWin::ScFunctionWin(weld::Widget* pParent)
     , pFuncDesc(nullptr)
 {
     InitLRUList();
+    UpdateFavouritesList();
 
     nArgs=0;
     m_aListHelpId = xFuncList->get_help_id();
@@ -141,6 +142,14 @@ void ScFunctionWin::InitLRUList()
         UpdateFunctionList(u""_ustr);
 }
 
+void ScFunctionWin::UpdateFavouritesList()
+{
+    ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
+    pFuncMgr->fillFavouriteFunctions(aFavouritesList);
+
+    if (xCatBox->get_active() == 0)
+        UpdateFunctionList(u""_ustr);
+}
 
 /*************************************************************************
 #*  Member:     FillCategoriesMap
@@ -263,16 +272,16 @@ void ScFunctionWin::UpdateFunctionList(const OUString& 
rSearchString)
 {
     sal_Int32  nSelPos   = xCatBox->get_active();
     sal_Int32  nCategory = ( -1 != nSelPos )
-                            ? (nSelPos-1) : 0;
+                            ? (nSelPos-ALL_CATEGORY) : 0;
 
     xFuncList->clear();
     xFuncList->freeze();
     mCategories.clear();
     sFuncScores.clear();
 
-    bool bCollapse = nCategory == 0;
+    bool bCollapse = nSelPos == ALL_CATEGORY;
     bool bFilter = !rSearchString.isEmpty();
-    if ( nSelPos > 0 )
+    if (nSelPos >= ALL_CATEGORY)
     {
         ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
 
@@ -314,7 +323,7 @@ void ScFunctionWin::UpdateFunctionList(const OUString& 
rSearchString)
                               xScratchIter.get());
         }
     }
-    else // LRU list
+    else if (nSelPos == LRU_CATEGORY) // LRU list
     {
         for (const formula::IFunctionDescription* pDesc : aLRUList)
         {
@@ -328,6 +337,22 @@ void ScFunctionWin::UpdateFunctionList(const OUString& 
rSearchString)
             }
         }
     }
+    else // Favourites List
+    {
+        ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
+        for (const auto& elem : aFavouritesList)
+        {
+            const formula::IFunctionDescription* pDesc(pFuncMgr->Get(elem));
+            if (pDesc)
+            {
+                OUString aFunction(pDesc->getFunctionName());
+                OUString aFuncDescId(weld::toId(pDesc));
+
+                xFuncList->insert(nullptr, -1, &aFunction, &aFuncDescId, 
nullptr, nullptr, false,
+                                  xScratchIter.get());
+            }
+        }
+    }
 
     xFuncList->thaw();
 
@@ -487,9 +512,9 @@ void ScFunctionWin::DoEnter(bool bDoubleOrEnter)
 
 IMPL_LINK_NOARG(ScFunctionWin, ModifyHdl, weld::Entry&, void)
 {
-    if (xCatBox->get_active() == 0)
+    if (xCatBox->get_active() == LRU_CATEGORY || xCatBox->get_active() == 
FAVOURITES_CATEGORY)
     {
-        xCatBox->set_active(1);
+        xCatBox->set_active(ALL_CATEGORY);
         xHelpButton->set_sensitive(false);
     }
     OUString searchStr = m_xSearchString->get_text();
@@ -591,10 +616,11 @@ IMPL_LINK(ScFunctionWin, KeyInputHdl, const KeyEvent&, 
rEvent, bool)
 
 IMPL_LINK_NOARG(ScFunctionWin, SelComboHdl, weld::ComboBox&, void)
 {
-    if (xCatBox->get_active() == 0)
+    if (xCatBox->get_active() == LRU_CATEGORY || xCatBox->get_active() == 
FAVOURITES_CATEGORY)
         m_xSearchString->set_text(u""_ustr);
-    xHelpButton->set_sensitive(xCatBox->get_active() != 1);
+    xHelpButton->set_sensitive(xCatBox->get_active() != ALL_CATEGORY);
     OUString searchStr = m_xSearchString->get_text();
+    UpdateFavouritesList();
     UpdateFunctionList(searchStr);
     SetDescription();
 }
diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx
index 9af2adbe7472..a2cd6b4e568a 100644
--- a/sc/source/ui/formdlg/formula.cxx
+++ b/sc/source/ui/formdlg/formula.cxx
@@ -512,6 +512,16 @@ void ScFormulaDlg::insertEntryToLRUList(const 
formula::IFunctionDescription*
     const ScFuncDesc* pDesc = dynamic_cast<const ScFuncDesc*>(_pDesc);
     SaveLRUEntry(pDesc);
 }
+
+void ScFormulaDlg::insertOrEraseFavouritesListEntry(const 
formula::IFunctionDescription* _pDesc, bool bInsert)
+{
+    const ScFuncDesc* pDesc = dynamic_cast<const ScFuncDesc*>(_pDesc);
+    if (pDesc && pDesc->nFIndex != 0)
+    {
+        ScModule::get()->InsertOrEraseFavouritesListEntry(pDesc->nFIndex, 
bInsert);
+    }
+}
+
 void ScFormulaDlg::showReference(const OUString& _sFormula)
 {
     ShowReference(_sFormula);
diff --git a/sc/source/ui/inc/dwfunctr.hxx b/sc/source/ui/inc/dwfunctr.hxx
index 9c05491dac2d..e66b02270cbe 100644
--- a/sc/source/ui/inc/dwfunctr.hxx
+++ b/sc/source/ui/inc/dwfunctr.hxx
@@ -63,9 +63,11 @@ private:
     ::std::set<std::pair<std::pair<sal_Int32, sal_Int32>, std::pair<OUString, 
const ScFuncDesc*>>>
                      sFuncScores;
     ::std::vector< const formula::IFunctionDescription*> aLRUList;
+    ::std::unordered_set<sal_uInt16> aFavouritesList;
     ::std::unordered_map<OUString, std::unique_ptr<weld::TreeIter>> 
mCategories;
 
     void            UpdateLRUList();
+    void            UpdateFavouritesList();
     void            DoEnter(bool bDouble_or_Enter = false);
     void            SetDescription();
     weld::TreeIter* FillCategoriesMap(const OUString&, bool);
diff --git a/sc/source/ui/inc/formula.hxx b/sc/source/ui/inc/formula.hxx
index 02ee866c1bc9..db6ef49f6b45 100644
--- a/sc/source/ui/inc/formula.hxx
+++ b/sc/source/ui/inc/formula.hxx
@@ -57,6 +57,7 @@ public:
     virtual std::unique_ptr<formula::FormulaCompiler> createCompiler( 
formula::FormulaTokenArray& rArray ) const override;
     virtual void doClose(bool _bOk) override;
     virtual void insertEntryToLRUList(const formula::IFunctionDescription*  
pDesc) override;
+    virtual void insertOrEraseFavouritesListEntry(const 
formula::IFunctionDescription* pDesc, bool bInsert) override;
     virtual void showReference(const OUString& _sFormula) override;
     virtual void dispatch(bool _bOK, bool _bMatrixChecked) override;
     virtual void setDispatcherLock( bool bLock ) override;
diff --git a/sc/uiconfig/scalc/ui/functionpanel.ui 
b/sc/uiconfig/scalc/ui/functionpanel.ui
index f2bade14020e..d9c68d35f4cf 100644
--- a/sc/uiconfig/scalc/ui/functionpanel.ui
+++ b/sc/uiconfig/scalc/ui/functionpanel.ui
@@ -67,6 +67,7 @@
                     <property name="hexpand">True</property>
                     <items>
                       <item translatable="yes" 
context="functionpanel|category">Last Used</item>
+                      <item translatable="yes" 
context="functionpanel|category">Favourites</item>
                       <item translatable="yes" 
context="functionpanel|category">All</item>
                       <item translatable="yes" 
context="functionpanel|category">Database</item>
                       <item translatable="yes" 
context="functionpanel|category">Date&amp;Time</item>

Reply via email to