sc/inc/strings.hrc                        |    1 
 sc/qa/uitest/autofilter2/tdf141559.py     |    4 
 sc/source/ui/cctrl/checklistmenu.cxx      |  152 +++++++++++++++++++++++-------
 sc/source/ui/inc/checklistmenu.hxx        |   19 ++-
 sc/source/ui/inc/gridwin.hxx              |    1 
 sc/source/ui/view/gridwin.cxx             |  135 +++++++++++++-------------
 sc/uiconfig/scalc/ui/filtersubdropdown.ui |  151 ++++++++++++++++++++++++++++-
 7 files changed, 346 insertions(+), 117 deletions(-)

New commits:
commit 8d3107f16d32fd0b582a0a5557691296791327f3
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Tue Dec 7 09:40:35 2021 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Wed Dec 8 10:58:41 2021 +0100

    tdf#146018 merge autofilter color dropdowns into a single dropdown
    
    Change-Id: Ie900ed2ebade82198928b3dc2e90ab7aa7f0edd0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126475
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sc/inc/strings.hrc b/sc/inc/strings.hrc
index 0cdbf7f1e540..006f1aadf85a 100644
--- a/sc/inc/strings.hrc
+++ b/sc/inc/strings.hrc
@@ -35,6 +35,7 @@
 #define SCSTR_TOP10FILTER                           NC_("SCSTR_TOP10FILTER", 
"Top 10")
 #define SCSTR_FILTER_EMPTY                          NC_("SCSTR_FILTER_EMPTY", 
"Empty")
 #define SCSTR_FILTER_NOTEMPTY                       
NC_("SCSTR_FILTER_NOTEMPTY", "Not Empty")
+#define SCSTR_FILTER_COLOR                          NC_("SCSTR_FILTER_COLOR", 
"Color Filter")
 #define SCSTR_FILTER_TEXT_COLOR                     
NC_("SCSTR_FILTER_TEXT_COLOR", "Text Color")
 #define SCSTR_FILTER_BACKGROUND_COLOR               
NC_("SCSTR_FILTER_BACKGROUND_COLOR", "Background Color")
 // This must match the translation of the same strings of 
standardfilterdialog|cond
diff --git a/sc/qa/uitest/autofilter2/tdf141559.py 
b/sc/qa/uitest/autofilter2/tdf141559.py
index 376720a2bd82..8ea7dbe6f3ee 100644
--- a/sc/qa/uitest/autofilter2/tdf141559.py
+++ b/sc/qa/uitest/autofilter2/tdf141559.py
@@ -37,7 +37,7 @@ class tdf141559(UITestCase):
 
             # check last item: 'Standard Filter...' (new menu item 'Clear 
Filter' is optional)
             nLastIdx = int(get_state_as_dict(xMenu)['Children']) - 1
-            self.assertEqual(10, nLastIdx)
+            self.assertEqual(8, nLastIdx)
             self.assertEqual('Standard Filter...', 
get_state_as_dict(xMenu.getChild(str(nLastIdx)))['Text'])
 
             xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
@@ -71,7 +71,7 @@ class tdf141559(UITestCase):
 
             # check last item: 'Clear Filter'
             nLastIdx = int(get_state_as_dict(xMenu)['Children']) - 1
-            self.assertEqual(11, nLastIdx)
+            self.assertEqual(9, nLastIdx)
             self.assertEqual('Clear Filter', 
get_state_as_dict(xMenu.getChild(str(nLastIdx)))['Text'])
 
             xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx 
b/sc/source/ui/cctrl/checklistmenu.cxx
index 83544df61145..a27fb53c09a4 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -179,12 +179,12 @@ void ScCheckListMenuControl::CreateDropDown()
                          DrawSymbolFlags::NONE);
 }
 
-ScListSubMenuControl* ScCheckListMenuControl::addSubMenuItem(const OUString& 
rText, bool bEnabled, bool bCheckList)
+ScListSubMenuControl* ScCheckListMenuControl::addSubMenuItem(const OUString& 
rText, bool bEnabled, bool bColorMenu)
 {
     MenuItemData aItem;
     aItem.mbEnabled = bEnabled;
 
-    aItem.mxSubMenuWin.reset(new ScListSubMenuControl(mxMenu.get(), *this, 
bCheckList, mpNotifier));
+    aItem.mxSubMenuWin.reset(new ScListSubMenuControl(mxMenu.get(), *this, 
bColorMenu, mpNotifier));
     maMenuItems.emplace_back(std::move(aItem));
 
     mxMenu->show();
@@ -1437,24 +1437,46 @@ int 
ScCheckListMenuControl::IncreaseWindowWidthToFitText(int nMaxTextWidth)
     return mnCheckWidthReq + nBorder;
 }
 
-ScListSubMenuControl::ScListSubMenuControl(weld::Widget* pParent, 
ScCheckListMenuControl& rParentControl, bool bCheckList, 
vcl::ILibreOfficeKitNotifier* pNotifier)
+ScListSubMenuControl::ScListSubMenuControl(weld::Widget* pParent, 
ScCheckListMenuControl& rParentControl, bool bColorMenu, 
vcl::ILibreOfficeKitNotifier* pNotifier)
     : mxBuilder(Application::CreateBuilder(pParent, 
"modules/scalc/ui/filtersubdropdown.ui"))
     , mxPopover(mxBuilder->weld_popover("FilterSubDropDown"))
     , mxContainer(mxBuilder->weld_container("container"))
     , mxMenu(mxBuilder->weld_tree_view("menu"))
+    , mxBackColorMenu(mxBuilder->weld_tree_view("background"))
+    , mxTextColorMenu(mxBuilder->weld_tree_view("textcolor"))
     , mxScratchIter(mxMenu->make_iterator())
     , mrParentControl(rParentControl)
     , mpNotifier(pNotifier)
+    , mnBackColorMenuPrefHeight(-1)
+    , mnTextColorMenuPrefHeight(-1)
+    , mbColorMenu(bColorMenu)
 {
-    if (bCheckList)
+    mxMenu->hide();
+    mxBackColorMenu->hide();
+    mxTextColorMenu->hide();
+
+    if (!bColorMenu)
     {
-        mxMenu->set_clicks_to_toggle(1);
-        mxMenu->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+        SetupMenu(*mxMenu);
+        mxMenu->show();
     }
+    else
+    {
+        mxBackColorMenu->set_clicks_to_toggle(1);
+        mxBackColorMenu->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+        mxBackColorMenu->connect_changed(LINK(this, ScListSubMenuControl, 
ColorSelChangedHdl));
+        mxTextColorMenu->set_clicks_to_toggle(1);
+        mxTextColorMenu->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+        mxTextColorMenu->connect_changed(LINK(this, ScListSubMenuControl, 
ColorSelChangedHdl));
+        SetupMenu(*mxBackColorMenu);
+        SetupMenu(*mxTextColorMenu);
+    }
+}
 
-    mxMenu->connect_row_activated(LINK(this, ScListSubMenuControl, 
RowActivatedHdl));
-    mxMenu->connect_toggled(LINK(this, ScListSubMenuControl, CheckToggledHdl));
-    mxMenu->connect_key_press(LINK(this, ScListSubMenuControl, 
MenuKeyInputHdl));
+void ScListSubMenuControl::SetupMenu(weld::TreeView& rMenu)
+{
+    rMenu.connect_row_activated(LINK(this, ScListSubMenuControl, 
RowActivatedHdl));
+    rMenu.connect_key_press(LINK(this, ScListSubMenuControl, MenuKeyInputHdl));
 }
 
 void ScListSubMenuControl::StartPopupMode(weld::Widget* pParent, const 
tools::Rectangle& rRect)
@@ -1464,8 +1486,9 @@ void ScListSubMenuControl::StartPopupMode(weld::Widget* 
pParent, const tools::Re
 
     mxPopover->popup_at_rect(pParent, rRect, weld::Placement::End);
 
-    mxMenu->set_cursor(0);
-    mxMenu->select(0);
+    weld::TreeView& rFirstMenu = mbColorMenu ? *mxBackColorMenu : *mxMenu;
+    rFirstMenu.set_cursor(0);
+    rFirstMenu.select(0);
 
     mrParentControl.setSubMenuFocused(this);
 }
@@ -1477,7 +1500,8 @@ void ScListSubMenuControl::EndPopupMode()
 
 void ScListSubMenuControl::GrabFocus()
 {
-    mxMenu->grab_focus();
+    weld::TreeView& rFirstMenu = mbColorMenu ? *mxBackColorMenu : *mxMenu;
+    rFirstMenu.grab_focus();
 }
 
 bool ScListSubMenuControl::IsVisible() const
@@ -1487,7 +1511,19 @@ bool ScListSubMenuControl::IsVisible() const
 
 void ScListSubMenuControl::resizeToFitMenuItems()
 {
-    mxMenu->set_size_request(-1, mxMenu->get_preferred_size().Height() + 2);
+    if (!mbColorMenu)
+        mxMenu->set_size_request(-1, mxMenu->get_preferred_size().Height());
+    else
+    {
+        int nBackColorMenuPrefHeight = mnBackColorMenuPrefHeight;
+        if (nBackColorMenuPrefHeight == -1)
+            nBackColorMenuPrefHeight = 
mxBackColorMenu->get_preferred_size().Height();
+        mxBackColorMenu->set_size_request(-1, nBackColorMenuPrefHeight);
+        int nTextColorMenuPrefHeight = mnTextColorMenuPrefHeight;
+        if (nTextColorMenuPrefHeight == -1)
+            nTextColorMenuPrefHeight = 
mxTextColorMenu->get_preferred_size().Height();
+        mxTextColorMenu->set_size_request(-1, nTextColorMenuPrefHeight);
+    }
 }
 
 void ScListSubMenuControl::addItem(ScCheckListMenuControl::Action* pAction)
@@ -1501,20 +1537,37 @@ void 
ScListSubMenuControl::addItem(ScCheckListMenuControl::Action* pAction)
 void ScListSubMenuControl::addMenuItem(const OUString& rText, 
ScCheckListMenuControl::Action* pAction)
 {
     addItem(pAction);
-    mxMenu->append_text(rText);
+    mxMenu->append(OUString::number(reinterpret_cast<sal_Int64>(pAction)), 
rText);
 }
 
-void ScListSubMenuControl::addMenuCheckItem(const OUString& rText, bool 
bActive, VirtualDevice& rImage, ScCheckListMenuControl::Action* pAction)
+void ScListSubMenuControl::addMenuColorItem(const OUString& rText, bool 
bActive, VirtualDevice& rImage,
+                                            int nMenu, 
ScCheckListMenuControl::Action* pAction)
 {
     addItem(pAction);
-    mxMenu->insert(nullptr, -1, &rText, nullptr, nullptr, &rImage, false, 
mxScratchIter.get());
-    mxMenu->set_toggle(*mxScratchIter, bActive ? TRISTATE_TRUE : 
TRISTATE_FALSE);
+
+    weld::TreeView& rColorMenu = nMenu == 0 ? *mxBackColorMenu : 
*mxTextColorMenu;
+    rColorMenu.show();
+
+    OUString sId = OUString::number(reinterpret_cast<sal_Int64>(pAction));
+    rColorMenu.insert(nullptr, -1, &rText, &sId, nullptr, nullptr, false, 
mxScratchIter.get());
+    rColorMenu.set_toggle(*mxScratchIter, bActive ? TRISTATE_TRUE : 
TRISTATE_FALSE);
+    rColorMenu.set_image(*mxScratchIter, rImage);
+
+    if (mnTextColorMenuPrefHeight == -1 && &rColorMenu == 
mxTextColorMenu.get() && mxTextColorMenu->n_children() == 8)
+        mnTextColorMenuPrefHeight = 
mxTextColorMenu->get_preferred_size().Height();
+
+    if (mnBackColorMenuPrefHeight == -1 && &rColorMenu == 
mxBackColorMenu.get() && mxBackColorMenu->n_children() == 8)
+        mnBackColorMenuPrefHeight = 
mxBackColorMenu->get_preferred_size().Height();
 }
 
 void ScListSubMenuControl::clearMenuItems()
 {
     maMenuItems.clear();
     mxMenu->clear();
+    mxBackColorMenu->clear();
+    mnBackColorMenuPrefHeight = -1;
+    mxTextColorMenu->clear();
+    mnTextColorMenuPrefHeight = -1;
 }
 
 IMPL_LINK(ScListSubMenuControl, MenuKeyInputHdl, const KeyEvent&, rKEvt, bool)
@@ -1534,8 +1587,39 @@ IMPL_LINK(ScListSubMenuControl, MenuKeyInputHdl, const 
KeyEvent&, rKEvt, bool)
         case KEY_SPACE:
         case KEY_RETURN:
         {
+            weld::TreeView& rMenu = !mbColorMenu ? *mxMenu :
+                                    (mxBackColorMenu->has_focus() ? 
*mxBackColorMenu : *mxTextColorMenu);
             // don't toggle checkbutton, go straight to activating entry
-            bConsumed = RowActivatedHdl(*mxMenu);
+            bConsumed = RowActivatedHdl(rMenu);
+            break;
+        }
+        case KEY_DOWN:
+        {
+            if (mxTextColorMenu->get_visible() &&
+                mxBackColorMenu->has_focus() &&
+                mxBackColorMenu->get_selected_index() == 
mxBackColorMenu->n_children() - 1)
+            {
+                mxBackColorMenu->unselect_all();
+                mxTextColorMenu->select(0);
+                mxTextColorMenu->set_cursor(0);
+                mxTextColorMenu->grab_focus();
+                bConsumed = true;
+            }
+            break;
+        }
+        case KEY_UP:
+        {
+            if (mxBackColorMenu->get_visible() &&
+                mxTextColorMenu->has_focus() &&
+                mxTextColorMenu->get_selected_index() == 0)
+            {
+                mxTextColorMenu->unselect_all();
+                int nIndex = mxBackColorMenu->n_children() - 1;
+                mxBackColorMenu->select(nIndex);
+                mxBackColorMenu->set_cursor(nIndex);
+                mxBackColorMenu->grab_focus();
+                bConsumed = true;
+            }
             break;
         }
     }
@@ -1543,32 +1627,30 @@ IMPL_LINK(ScListSubMenuControl, MenuKeyInputHdl, const 
KeyEvent&, rKEvt, bool)
     return bConsumed;
 }
 
-IMPL_LINK_NOARG(ScListSubMenuControl, RowActivatedHdl, weld::TreeView&, bool)
+IMPL_LINK(ScListSubMenuControl, ColorSelChangedHdl, weld::TreeView&, rMenu, 
void)
 {
-    executeMenuItem(mxMenu->get_selected_index());
-    return true;
+    if (rMenu.get_selected_index() == -1)
+        return;
+    if (&rMenu != mxTextColorMenu.get())
+        mxTextColorMenu->unselect_all();
+    else
+        mxBackColorMenu->unselect_all();
+    rMenu.grab_focus();
 }
 
-IMPL_LINK(ScListSubMenuControl, CheckToggledHdl, const 
weld::TreeView::iter_col&, rRowCol, void)
+IMPL_LINK(ScListSubMenuControl, RowActivatedHdl, weld::TreeView&, rMenu, bool)
 {
-    mxMenu->all_foreach([this, &rRowCol](weld::TreeIter& rEntry){
-        bool bToggledEntry = mxMenu->iter_compare(rEntry, rRowCol.first) == 0;
-        if (!bToggledEntry)
-            mxMenu->set_toggle(rEntry, TRISTATE_FALSE);
-        return false;
-    });
+    
executeMenuItem(reinterpret_cast<ScCheckListMenuControl::Action*>(rMenu.get_selected_id().toInt64()));
+    return true;
 }
 
-void ScListSubMenuControl::executeMenuItem(size_t nPos)
+void ScListSubMenuControl::executeMenuItem(ScCheckListMenuControl::Action* 
pAction)
 {
-    if (nPos >= maMenuItems.size())
+    // if no action is defined.
+    if (!pAction)
         return;
 
-    if (!maMenuItems[nPos].mxAction)
-        // no action is defined.
-        return;
-
-    const bool bClosePopup = maMenuItems[nPos].mxAction->execute();
+    const bool bClosePopup = pAction->execute();
     if (bClosePopup)
         terminateAllPopupMenus();
 }
diff --git a/sc/source/ui/inc/checklistmenu.hxx 
b/sc/source/ui/inc/checklistmenu.hxx
index 4ba29de52166..bf38ea081f10 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -129,7 +129,7 @@ public:
 
     void addMenuItem(const OUString& rText, Action* pAction);
     void addSeparator();
-    ScListSubMenuControl* addSubMenuItem(const OUString& rText, bool bEnabled, 
bool bCheckList);
+    ScListSubMenuControl* addSubMenuItem(const OUString& rText, bool bEnabled, 
bool bColorMenu);
 
     void selectMenuItem(size_t nPos, bool bSubMenuTimer);
     void queueLaunchSubMenu(size_t nPos, ScListSubMenuControl* pMenu);
@@ -321,7 +321,7 @@ private:
 class ScListSubMenuControl final
 {
 public:
-    ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& 
rParentControl, bool bCheckList, vcl::ILibreOfficeKitNotifier* pNotifier);
+    ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& 
rParentControl, bool bColorMenu, vcl::ILibreOfficeKitNotifier* pNotifier);
 
     void setPopupStartAction(ScCheckListMenuControl::Action* p);
 
@@ -332,7 +332,9 @@ public:
     void EndPopupMode();
 
     void addMenuItem(const OUString& rText, ScCheckListMenuControl::Action* 
pAction);
-    void addMenuCheckItem(const OUString& rText, bool bActive, VirtualDevice& 
rImage, ScCheckListMenuControl::Action* pAction);
+    // nMenu of 0 for background color, nMenu of 1 for text color
+    void addMenuColorItem(const OUString& rText, bool bActive, VirtualDevice& 
rImage,
+                          int nMenu, ScCheckListMenuControl::Action* pAction);
     void clearMenuItems();
     void resizeToFitMenuItems();
 
@@ -351,18 +353,25 @@ private:
     std::unique_ptr<weld::Popover> mxPopover;
     std::unique_ptr<weld::Container> mxContainer;
     std::unique_ptr<weld::TreeView> mxMenu;
+    std::unique_ptr<weld::TreeView> mxBackColorMenu;
+    std::unique_ptr<weld::TreeView> mxTextColorMenu;
     std::unique_ptr<weld::TreeIter> mxScratchIter;
     std::unique_ptr<ScCheckListMenuControl::Action> mxPopupStartAction;
     std::vector<ScCheckListMenuControl::MenuItemData> maMenuItems;
     ScCheckListMenuControl& mrParentControl;
     vcl::ILibreOfficeKitNotifier* mpNotifier;
+    int mnBackColorMenuPrefHeight;
+    int mnTextColorMenuPrefHeight;
+    bool mbColorMenu;
 
     DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
-    DECL_LINK(CheckToggledHdl, const weld::TreeView::iter_col&, void);
+    DECL_LINK(ColorSelChangedHdl, weld::TreeView&, void);
     DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
 
+    void SetupMenu(weld::TreeView& rMenu);
+
     void NotifyCloseLOK();
-    void executeMenuItem(size_t nPos);
+    void executeMenuItem(ScCheckListMenuControl::Action* pAction);
     void addItem(ScCheckListMenuControl::Action* pAction);
 };
 
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index 2f8ac0deacfc..419a29e74560 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -330,6 +330,7 @@ protected:
 public:
     enum class AutoFilterMode
     {
+        None,
         Normal,
         Top10,
         Custom,
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index ad779997bde7..c6a0cac1daf6 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -634,8 +634,8 @@ public:
 class AutoFilterColorPopupStartAction : public AutoFilterSubMenuAction
 {
 public:
-    AutoFilterColorPopupStartAction(ScGridWindow* p, ScListSubMenuControl* 
pSubMenu, ScGridWindow::AutoFilterMode eMode)
-        : AutoFilterSubMenuAction(p, pSubMenu, eMode)
+    AutoFilterColorPopupStartAction(ScGridWindow* p, ScListSubMenuControl* 
pSubMenu)
+        : AutoFilterSubMenuAction(p, pSubMenu, 
ScGridWindow::AutoFilterMode::None)
     {
     }
 
@@ -660,10 +660,6 @@ public:
 
         m_pSubMenu->clearMenuItems();
 
-        std::set<Color> aColors = meMode == 
ScGridWindow::AutoFilterMode::TextColor
-                                      ? aFilterEntries.getTextColors()
-                                      : aFilterEntries.getBackgroundColors();
-
         XColorListRef xUserColorList;
 
         OUString 
aPaletteName(officecfg::Office::Common::UserColors::PaletteName::get());
@@ -687,76 +683,86 @@ public:
         pDBData->GetQueryParam(aParam);
         ScQueryEntry* pEntry = aParam.FindEntryByField(rPos.Col(), true);
 
-        for (auto& rColor : aColors)
+        int nMenu = 0;
+        for (auto eMode : {ScGridWindow::AutoFilterMode::BackgroundColor, 
ScGridWindow::AutoFilterMode::TextColor})
         {
-            bool bActive = false;
+            std::set<Color> aColors = eMode == 
ScGridWindow::AutoFilterMode::TextColor
+                                          ? aFilterEntries.getTextColors()
+                                          : 
aFilterEntries.getBackgroundColors();
 
-            if (pEntry)
+            for (auto& rColor : aColors)
             {
-                auto aItem = pEntry->GetQueryItem();
-                if (aItem.maColor == rColor
-                    && ((meMode == ScGridWindow::AutoFilterMode::TextColor
-                         && aItem.meType == ScQueryEntry::ByTextColor)
-                        || (meMode == 
ScGridWindow::AutoFilterMode::BackgroundColor
-                            && aItem.meType == 
ScQueryEntry::ByBackgroundColor)))
+                bool bActive = false;
+
+                if (pEntry)
                 {
-                    bActive = true;
+                    auto aItem = pEntry->GetQueryItem();
+                    if (aItem.maColor == rColor
+                        && ((eMode == ScGridWindow::AutoFilterMode::TextColor
+                             && aItem.meType == ScQueryEntry::ByTextColor)
+                            || (eMode == 
ScGridWindow::AutoFilterMode::BackgroundColor
+                                && aItem.meType == 
ScQueryEntry::ByBackgroundColor)))
+                    {
+                        bActive = true;
+                    }
                 }
-            }
 
-            const bool bAutoColor = rColor == COL_AUTO;
+                const bool bAutoColor = rColor == COL_AUTO;
 
-            // ColorListBox::ShowPreview is similar
-            ScopedVclPtr<VirtualDevice> 
xDev(m_pSubMenu->create_virtual_device());
-            const StyleSettings& rStyleSettings = 
Application::GetSettings().GetStyleSettings();
-            Size 
aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize());
-            xDev->SetOutputSize(aImageSize);
-            const tools::Rectangle aRect(Point(0, 0), aImageSize);
+                // ColorListBox::ShowPreview is similar
+                ScopedVclPtr<VirtualDevice> 
xDev(m_pSubMenu->create_virtual_device());
+                const StyleSettings& rStyleSettings = 
Application::GetSettings().GetStyleSettings();
+                Size 
aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize());
+                xDev->SetOutputSize(aImageSize);
+                const tools::Rectangle aRect(Point(0, 0), aImageSize);
 
-            if (bAutoColor)
-            {
-                const Color aW(COL_WHITE);
-                const Color aG(0xef, 0xef, 0xef);
-                int nMinDim = std::min(aImageSize.Width(), 
aImageSize.Height()) + 1;
-                int nCheckSize = nMinDim / 3;
-                xDev->DrawCheckered(aRect.TopLeft(), aRect.GetSize(), 
std::min(nCheckSize, 8), aW, aG);
-                xDev->SetFillColor();
-            }
-            else
-                xDev->SetFillColor(rColor);
+                if (bAutoColor)
+                {
+                    const Color aW(COL_WHITE);
+                    const Color aG(0xef, 0xef, 0xef);
+                    int nMinDim = std::min(aImageSize.Width(), 
aImageSize.Height()) + 1;
+                    int nCheckSize = nMinDim / 3;
+                    xDev->DrawCheckered(aRect.TopLeft(), aRect.GetSize(), 
std::min(nCheckSize, 8), aW, aG);
+                    xDev->SetFillColor();
+                }
+                else
+                    xDev->SetFillColor(rColor);
 
-            xDev->SetLineColor(rStyleSettings.GetDisableColor());
-            xDev->DrawRect(aRect);
+                xDev->SetLineColor(rStyleSettings.GetDisableColor());
+                xDev->DrawRect(aRect);
 
-            if (bAutoColor)
-            {
-                OUString sText = meMode == 
ScGridWindow::AutoFilterMode::TextColor
-                                     ? ScResId(SCSTR_FILTER_AUTOMATIC_COLOR)
-                                     : ScResId(SCSTR_FILTER_NO_FILL);
-                m_pSubMenu->addMenuCheckItem(sText, bActive, *xDev,
-                                             new 
AutoFilterColorAction(mpWindow, m_pSubMenu, meMode, rColor));
-            }
-            else
-            {
-                OUString sName;
-
-                bool bFoundColorName = false;
-                if (xUserColorList)
+                if (bAutoColor)
                 {
-                    sal_Int32 nPos = xUserColorList->GetIndexOfColor(rColor);
-                    if (nPos != -1)
+                    OUString sText = eMode == 
ScGridWindow::AutoFilterMode::TextColor
+                                         ? 
ScResId(SCSTR_FILTER_AUTOMATIC_COLOR)
+                                         : ScResId(SCSTR_FILTER_NO_FILL);
+                    m_pSubMenu->addMenuColorItem(sText, bActive, *xDev, nMenu,
+                                                 new 
AutoFilterColorAction(mpWindow, m_pSubMenu, eMode, rColor));
+                }
+                else
+                {
+                    OUString sName;
+
+                    bool bFoundColorName = false;
+                    if (xUserColorList)
                     {
-                        XColorEntry* pColorEntry = 
xUserColorList->GetColor(nPos);
-                        sName = pColorEntry->GetName();
-                        bFoundColorName = true;
+                        sal_Int32 nPos = 
xUserColorList->GetIndexOfColor(rColor);
+                        if (nPos != -1)
+                        {
+                            XColorEntry* pColorEntry = 
xUserColorList->GetColor(nPos);
+                            sName = pColorEntry->GetName();
+                            bFoundColorName = true;
+                        }
                     }
-                }
-                if (!bFoundColorName)
-                    sName = "#" + rColor.AsRGBHexString().toAsciiUpperCase();
+                    if (!bFoundColorName)
+                        sName = "#" + 
rColor.AsRGBHexString().toAsciiUpperCase();
 
-                m_pSubMenu->addMenuCheckItem(sName, bActive, *xDev,
-                                             new 
AutoFilterColorAction(mpWindow, m_pSubMenu, meMode, rColor));
+                    m_pSubMenu->addMenuColorItem(sName, bActive, *xDev, nMenu,
+                                                 new 
AutoFilterColorAction(mpWindow, m_pSubMenu, eMode, rColor));
+                }
             }
+
+            ++nMenu;
         }
 
         m_pSubMenu->resizeToFitMenuItems();
@@ -977,11 +983,8 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW 
nRow)
     mpAutoFilterPopup->addMenuItem(
         ScResId(SCSTR_FILTER_NOTEMPTY), new AutoFilterAction(this, 
AutoFilterMode::NonEmpty));
     mpAutoFilterPopup->addSeparator();
-    if (ScListSubMenuControl* pSubMenu = 
mpAutoFilterPopup->addSubMenuItem(ScResId(SCSTR_FILTER_TEXT_COLOR), true, true))
-        pSubMenu->setPopupStartAction(new 
AutoFilterColorPopupStartAction(this, pSubMenu, AutoFilterMode::TextColor));
-    if (ScListSubMenuControl* pSubMenu = 
mpAutoFilterPopup->addSubMenuItem(ScResId(SCSTR_FILTER_BACKGROUND_COLOR), true, 
true))
-        pSubMenu->setPopupStartAction(new 
AutoFilterColorPopupStartAction(this, pSubMenu, 
AutoFilterMode::BackgroundColor));
-    mpAutoFilterPopup->addSeparator();
+    if (ScListSubMenuControl* pSubMenu = 
mpAutoFilterPopup->addSubMenuItem(ScResId(SCSTR_FILTER_COLOR), true, true))
+        pSubMenu->setPopupStartAction(new 
AutoFilterColorPopupStartAction(this, pSubMenu));
     mpAutoFilterPopup->addMenuItem(
         ScResId(SCSTR_STDFILTER), new AutoFilterAction(this, 
AutoFilterMode::Custom));
     if (aEntries.size())
diff --git a/sc/uiconfig/scalc/ui/filtersubdropdown.ui 
b/sc/uiconfig/scalc/ui/filtersubdropdown.ui
index eb9d3444032c..2cb944e97861 100644
--- a/sc/uiconfig/scalc/ui/filtersubdropdown.ui
+++ b/sc/uiconfig/scalc/ui/filtersubdropdown.ui
@@ -6,8 +6,40 @@
     <columns>
       <!-- column-name check1 -->
       <column type="gboolean"/>
-      <!-- column-name surface -->
-      <column type="CairoSurface"/>
+      <!-- column-name pixbuf -->
+      <column type="GdkPixbuf"/>
+      <!-- column-name text1 -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+      <!-- column-name checkvis1 -->
+      <column type="gboolean"/>
+      <!-- column-name checktri1 -->
+      <column type="gboolean"/>
+    </columns>
+  </object>
+  <object class="GtkListStore" id="liststore2">
+    <columns>
+      <!-- column-name check1 -->
+      <column type="gboolean"/>
+      <!-- column-name pixbuf -->
+      <column type="GdkPixbuf"/>
+      <!-- column-name text1 -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+      <!-- column-name checkvis1 -->
+      <column type="gboolean"/>
+      <!-- column-name checktri1 -->
+      <column type="gboolean"/>
+    </columns>
+  </object>
+  <object class="GtkListStore" id="liststore3">
+    <columns>
+      <!-- column-name check1 -->
+      <column type="gboolean"/>
+      <!-- column-name pixbuf -->
+      <column type="GdkPixbuf"/>
       <!-- column-name text1 -->
       <column type="gchararray"/>
       <!-- column-name id -->
@@ -38,7 +70,6 @@
             <property name="vexpand">True</property>
             <property name="hscrollbar-policy">never</property>
             <property name="vscrollbar-policy">never</property>
-            <property name="shadow-type">in</property>
             <child>
               <object class="GtkTreeView" id="menu">
                 <property name="visible">True</property>
@@ -64,22 +95,124 @@
                         <attribute name="active">0</attribute>
                       </attributes>
                     </child>
+                    <child>
+                      <object class="GtkCellRendererPixbuf" 
id="cellrendererpixbuf"/>
+                      <attributes>
+                        <attribute name="pixbuf">1</attribute>
+                      </attributes>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererText" 
id="cellrenderertext"/>
+                      <attributes>
+                        <attribute name="text">2</attribute>
+                      </attributes>
+                    </child>
                   </object>
                 </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="valign">center</property>
+            <property name="vexpand">True</property>
+            <property name="hscrollbar-policy">never</property>
+            <child>
+              <object class="GtkTreeView" id="background">
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="valign">center</property>
+                <property name="vexpand">True</property>
+                <property name="model">liststore2</property>
+                <property name="headers-clickable">False</property>
+                <property name="search-column">0</property>
+                <property name="hover-selection">True</property>
+                <property name="show-expanders">False</property>
+                <property name="activate-on-single-click">True</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection"/>
+                </child>
                 <child>
-                  <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                  <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+                    <property name="title" translatable="yes" 
context="filtersubdropdown|background">Background Color</property>
                     <child>
-                      <object class="GtkCellRendererPixbuf" 
id="cellrendererpixbuf"/>
+                      <object class="GtkCellRendererToggle" 
id="cellrenderertoggle1"/>
+                      <attributes>
+                        <attribute name="visible">4</attribute>
+                        <attribute name="active">0</attribute>
+                      </attributes>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererPixbuf" 
id="cellrendererpixbuf1"/>
+                      <attributes>
+                        <attribute name="pixbuf">1</attribute>
+                      </attributes>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererText" 
id="cellrenderertext1"/>
                       <attributes>
-                        <attribute name="surface">1</attribute>
+                        <attribute name="text">2</attribute>
                       </attributes>
                     </child>
                   </object>
                 </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="valign">center</property>
+            <property name="vexpand">True</property>
+            <property name="hscrollbar-policy">never</property>
+            <child>
+              <object class="GtkTreeView" id="textcolor">
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="valign">center</property>
+                <property name="vexpand">True</property>
+                <property name="model">liststore3</property>
+                <property name="headers-clickable">False</property>
+                <property name="search-column">0</property>
+                <property name="hover-selection">True</property>
+                <property name="show-expanders">False</property>
+                <property name="activate-on-single-click">True</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection"/>
+                </child>
                 <child>
-                  <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+                  <object class="GtkTreeViewColumn" id="treeviewcolumn7">
+                    <property name="title" translatable="yes" 
context="filtersubdropdown|textcolor">Text Color</property>
                     <child>
-                      <object class="GtkCellRendererText" 
id="cellrenderertext"/>
+                      <object class="GtkCellRendererToggle" 
id="cellrenderertoggle2"/>
+                      <attributes>
+                        <attribute name="visible">4</attribute>
+                        <attribute name="active">0</attribute>
+                      </attributes>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererPixbuf" 
id="cellrendererpixbuf2"/>
+                      <attributes>
+                        <attribute name="pixbuf">1</attribute>
+                      </attributes>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererText" 
id="cellrenderertext2"/>
                       <attributes>
                         <attribute name="text">2</attribute>
                       </attributes>
@@ -92,7 +225,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="position">0</property>
+            <property name="position">2</property>
           </packing>
         </child>
       </object>

Reply via email to