summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2021-11-29 12:55:38 +0000
committerCaolán McNamara <caolanm@redhat.com>2021-12-02 23:27:27 +0100
commit29145df0977baa866e7da94d1d385b772ae1e6ce (patch)
treeae4c89322b0879a1b8451d23158dcf8b65195d15
parent5346168fa919ad98224c4d2079e738a4d0b8d164 (diff)
Resolves: tdf#144811 use the hover-style menu for color submenus
Change-Id: I8653c36d084f9df5a4d34baf7d88e2f2b5f1609b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126209 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sc/source/ui/cctrl/checklistmenu.cxx74
-rw-r--r--sc/source/ui/inc/checklistmenu.hxx28
-rw-r--r--sc/source/ui/view/gridwin.cxx344
-rw-r--r--sc/source/ui/view/gridwin2.cxx4
-rw-r--r--sc/uiconfig/scalc/ui/filtersubdropdown.ui33
5 files changed, 359 insertions, 124 deletions
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index f4caff97e8ad..7e0c9fc5c03c 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -38,6 +38,8 @@
#include <vcl/jsdialog/executor.hxx>
#include <document.hxx>
+#include <docsh.hxx>
+#include <viewdata.hxx>
using namespace com::sun::star;
using ::com::sun::star::uno::Reference;
@@ -120,7 +122,7 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, SelectHdl, weld::TreeView&, void)
setSelectedMenuItem(nSelectedMenu, true);
}
-void ScCheckListMenuControl::addMenuItem(const OUString& rText, Action* pAction, bool bIndicateSubMenu)
+void ScCheckListMenuControl::addMenuItem(const OUString& rText, Action* pAction)
{
MenuItemData aItem;
aItem.mbEnabled = true;
@@ -129,10 +131,7 @@ void ScCheckListMenuControl::addMenuItem(const OUString& rText, Action* pAction,
mxMenu->show();
mxMenu->append_text(rText);
- if (bIndicateSubMenu)
- mxMenu->set_image(mxMenu->n_children() - 1, *mxDropDown, 1);
- else
- mxMenu->set_image(mxMenu->n_children() - 1, css::uno::Reference<css::graphic::XGraphic>(), 1);
+ mxMenu->set_image(mxMenu->n_children() - 1, css::uno::Reference<css::graphic::XGraphic>(), 1);
}
void ScCheckListMenuControl::addSeparator()
@@ -180,12 +179,12 @@ void ScCheckListMenuControl::CreateDropDown()
DrawSymbolFlags::NONE);
}
-ScListSubMenuControl* ScCheckListMenuControl::addSubMenuItem(const OUString& rText, bool bEnabled)
+ScListSubMenuControl* ScCheckListMenuControl::addSubMenuItem(const OUString& rText, bool bEnabled, bool bCheckList)
{
MenuItemData aItem;
aItem.mbEnabled = bEnabled;
- aItem.mxSubMenuWin.reset(new ScListSubMenuControl(mxMenu.get(), *this, mpNotifier));
+ aItem.mxSubMenuWin.reset(new ScListSubMenuControl(mxMenu.get(), *this, bCheckList, mpNotifier));
maMenuItems.emplace_back(std::move(aItem));
mxMenu->show();
@@ -451,7 +450,7 @@ constexpr int nBorderWidth = 4;
// number of rows visible in checklist
constexpr int nCheckListVisibleRows = 8;
-ScCheckListMenuControl::ScCheckListMenuControl(weld::Widget* pParent, ScDocument* pDoc,
+ScCheckListMenuControl::ScCheckListMenuControl(weld::Widget* pParent, ScViewData& rViewData,
bool bHasDates, int nWidth, vcl::ILibreOfficeKitNotifier* pNotifier)
: mxBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/filterdropdown.ui"))
, mxPopover(mxBuilder->weld_popover("FilterDropDown"))
@@ -474,7 +473,7 @@ ScCheckListMenuControl::ScCheckListMenuControl(weld::Widget* pParent, ScDocument
, mnWndWidth(0)
, mePrevToggleAllState(TRISTATE_INDET)
, mnSelectedMenu(MENU_NOT_SELECTED)
- , mpDoc(pDoc)
+ , mrViewData(rViewData)
, mnAsyncPostPopdownId(nullptr)
, mnAsyncSetDropdownPosId(nullptr)
, mpNotifier(pNotifier)
@@ -890,7 +889,7 @@ void ScCheckListMenuControl::setMemberSize(size_t n)
void ScCheckListMenuControl::addDateMember(const OUString& rsName, double nVal, bool bVisible)
{
- SvNumberFormatter* pFormatter = mpDoc->GetFormatTable();
+ SvNumberFormatter* pFormatter = mrViewData.GetDocument().GetFormatTable();
// Convert the numeric date value to a date object.
Date aDate = pFormatter->GetNullDate();
@@ -1448,7 +1447,7 @@ int ScCheckListMenuControl::IncreaseWindowWidthToFitText(int nMaxTextWidth)
return mnCheckWidthReq + nBorder;
}
-ScListSubMenuControl::ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& rParentControl, vcl::ILibreOfficeKitNotifier* pNotifier)
+ScListSubMenuControl::ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& rParentControl, bool bCheckList, vcl::ILibreOfficeKitNotifier* pNotifier)
: mxBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/filtersubdropdown.ui"))
, mxPopover(mxBuilder->weld_popover("FilterSubDropDown"))
, mxContainer(mxBuilder->weld_container("container"))
@@ -1457,12 +1456,22 @@ ScListSubMenuControl::ScListSubMenuControl(weld::Widget* pParent, ScCheckListMen
, mrParentControl(rParentControl)
, mpNotifier(pNotifier)
{
+ if (bCheckList)
+ {
+ mxMenu->set_clicks_to_toggle(1);
+ mxMenu->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+ }
+
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::StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect)
{
+ if (mxPopupStartAction)
+ mxPopupStartAction->execute();
+
mxPopover->popup_at_rect(pParent, rRect, weld::Placement::End);
mxMenu->set_cursor(0);
@@ -1491,16 +1500,33 @@ void ScListSubMenuControl::resizeToFitMenuItems()
mxMenu->set_size_request(-1, mxMenu->get_preferred_size().Height() + 2);
}
-void ScListSubMenuControl::addMenuItem(const OUString& rText, ScCheckListMenuControl::Action* pAction)
+void ScListSubMenuControl::addItem(ScCheckListMenuControl::Action* pAction)
{
ScCheckListMenuControl::MenuItemData aItem;
aItem.mbEnabled = true;
aItem.mxAction.reset(pAction);
maMenuItems.emplace_back(std::move(aItem));
- mxMenu->show();
+}
+
+void ScListSubMenuControl::addMenuItem(const OUString& rText, ScCheckListMenuControl::Action* pAction)
+{
+ addItem(pAction);
mxMenu->append_text(rText);
}
+void ScListSubMenuControl::addMenuCheckItem(const OUString& rText, bool bActive, VirtualDevice& rImage, 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);
+}
+
+void ScListSubMenuControl::clearMenuItems()
+{
+ maMenuItems.clear();
+ mxMenu->clear();
+}
+
IMPL_LINK(ScListSubMenuControl, MenuKeyInputHdl, const KeyEvent&, rKEvt, bool)
{
bool bConsumed = false;
@@ -1515,6 +1541,13 @@ IMPL_LINK(ScListSubMenuControl, MenuKeyInputHdl, const KeyEvent&, rKEvt, bool)
bConsumed = true;
break;
}
+ case KEY_SPACE:
+ case KEY_RETURN:
+ {
+ // don't toggle checkbutton, go straight to activating entry
+ bConsumed = RowActivatedHdl(*mxMenu);
+ break;
+ }
}
return bConsumed;
@@ -1526,6 +1559,16 @@ IMPL_LINK_NOARG(ScListSubMenuControl, RowActivatedHdl, weld::TreeView&, bool)
return true;
}
+IMPL_LINK(ScListSubMenuControl, CheckToggledHdl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ 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;
+ });
+}
+
void ScListSubMenuControl::executeMenuItem(size_t nPos)
{
if (nPos >= maMenuItems.size())
@@ -1540,6 +1583,11 @@ void ScListSubMenuControl::executeMenuItem(size_t nPos)
terminateAllPopupMenus();
}
+void ScListSubMenuControl::setPopupStartAction(ScCheckListMenuControl::Action* p)
+{
+ mxPopupStartAction.reset(p);
+}
+
void ScListSubMenuControl::terminateAllPopupMenus()
{
if (comphelper::LibreOfficeKit::isActive())
diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx
index 6a5dbceb1966..961fddceac58 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -11,6 +11,7 @@
#include <vcl/dockwin.hxx>
#include <vcl/timer.hxx>
+#include <vcl/virdev.hxx>
#include <vcl/weld.hxx>
#include <memory>
@@ -18,10 +19,8 @@
#include <map>
#include <set>
-class ScDocument;
-
class ScCheckListMenuControl;
-
+class ScViewData;
struct ScCheckListMember;
struct ScCheckListMember
@@ -123,14 +122,14 @@ public:
Config();
};
- ScCheckListMenuControl(weld::Widget* pParent, ScDocument* pDoc,
+ ScCheckListMenuControl(weld::Widget* pParent, ScViewData& rViewData,
bool bTreeMode, int nWidth,
vcl::ILibreOfficeKitNotifier* pNotifier);
~ScCheckListMenuControl();
- void addMenuItem(const OUString& rText, Action* pAction, bool bIndicateSubMenu = false);
+ void addMenuItem(const OUString& rText, Action* pAction);
void addSeparator();
- ScListSubMenuControl* addSubMenuItem(const OUString& rText, bool bEnabled);
+ ScListSubMenuControl* addSubMenuItem(const OUString& rText, bool bEnabled, bool bCheckList);
void resizeToFitMenuItems();
void selectMenuItem(size_t nPos, bool bSubMenuTimer);
@@ -168,6 +167,8 @@ public:
*/
ExtendedData* getExtendedData();
+ ScViewData& GetViewData() const { return mrViewData; }
+
void GrabFocus();
void setOKAction(Action* p);
@@ -292,7 +293,7 @@ private:
size_t mnSelectedMenu;
- ScDocument* mpDoc;
+ ScViewData& mrViewData;
ImplSVEvent* mnAsyncPostPopdownId;
ImplSVEvent* mnAsyncSetDropdownPosId;
@@ -323,7 +324,9 @@ private:
class ScListSubMenuControl final
{
public:
- ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& rParentControl, vcl::ILibreOfficeKitNotifier* pNotifier);
+ ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& rParentControl, bool bCheckList, vcl::ILibreOfficeKitNotifier* pNotifier);
+
+ void setPopupStartAction(ScCheckListMenuControl::Action* p);
void GrabFocus();
bool IsVisible() const;
@@ -332,10 +335,16 @@ public:
void EndPopupMode();
void addMenuItem(const OUString& rText, ScCheckListMenuControl::Action* pAction);
+ void addMenuCheckItem(const OUString& rText, bool bActive, VirtualDevice& rImage, ScCheckListMenuControl::Action* pAction);
+ void clearMenuItems();
void resizeToFitMenuItems();
void setSelectedMenuItem(size_t nPos);
+ ScViewData& GetViewData() const { return mrParentControl.GetViewData(); }
+ ScCheckListMenuControl::ExtendedData* getExtendedData() { return mrParentControl.getExtendedData(); }
+ VclPtr<VirtualDevice> create_virtual_device() const { return mxMenu->create_virtual_device(); }
+
/**
* Dismiss all visible popup menus and set focus back to the application
* window. This method is called e.g. when a menu action is fired.
@@ -348,15 +357,18 @@ private:
std::unique_ptr<weld::Container> mxContainer;
std::unique_ptr<weld::TreeView> mxMenu;
std::unique_ptr<weld::TreeIter> mxScratchIter;
+ std::unique_ptr<ScCheckListMenuControl::Action> mxPopupStartAction;
std::vector<ScCheckListMenuControl::MenuItemData> maMenuItems;
ScCheckListMenuControl& mrParentControl;
vcl::ILibreOfficeKitNotifier* mpNotifier;
DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
+ DECL_LINK(CheckToggledHdl, const weld::TreeView::iter_col&, void);
DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
void NotifyCloseLOK();
void executeMenuItem(size_t nPos);
+ void addItem(ScCheckListMenuControl::Action* pAction);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 81be88882264..dd24eb941a26 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -24,12 +24,13 @@
#include <editeng/adjustitem.hxx>
#include <sot/storage.hxx>
#include <editeng/eeitem.hxx>
-#include <editeng/editview.hxx>
+#include <editeng/editobj.hxx>
#include <editeng/editstat.hxx>
+#include <editeng/editview.hxx>
#include <editeng/flditem.hxx>
#include <editeng/justifyitem.hxx>
+#include <editeng/outliner.hxx>
#include <editeng/misspellrange.hxx>
-#include <editeng/editobj.hxx>
#include <o3tl/unit_conversion.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
@@ -48,8 +49,8 @@
#include <sot/formats.hxx>
#include <comphelper/classids.hxx>
+#include <svx/drawitem.hxx>
#include <svx/svdview.hxx>
-#include <editeng/outliner.hxx>
#include <svx/svdocapt.hxx>
#include <svx/svdpagv.hxx>
#include <svtools/optionsdrawinglayer.hxx>
@@ -127,6 +128,9 @@
#include <inputopt.hxx>
#include <queryparam.hxx>
+#include <officecfg/Office/Common.hxx>
+
+#include <svx/PaletteManager.hxx>
#include <svx/sdrpagewindow.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <vcl/svapp.hxx>
@@ -495,6 +499,7 @@ struct AutoFilterData : public ScCheckListMenuControl::ExtendedData
class AutoFilterAction : public ScCheckListMenuControl::Action
{
+protected:
VclPtr<ScGridWindow> mpWindow;
ScGridWindow::AutoFilterMode meMode;
public:
@@ -523,6 +528,242 @@ public:
}
};
+class AutoFilterSubMenuAction : public AutoFilterAction
+{
+protected:
+ ScListSubMenuControl* m_pSubMenu;
+
+public:
+ AutoFilterSubMenuAction(ScGridWindow* p, ScListSubMenuControl* pSubMenu, ScGridWindow::AutoFilterMode eMode)
+ : AutoFilterAction(p, eMode)
+ , m_pSubMenu(pSubMenu)
+ {
+ }
+};
+
+class AutoFilterColorAction : public AutoFilterSubMenuAction
+{
+private:
+ Color m_aColor;
+
+public:
+ AutoFilterColorAction(ScGridWindow* p, ScListSubMenuControl* pSubMenu, ScGridWindow::AutoFilterMode eMode, const Color& rColor)
+ : AutoFilterSubMenuAction(p, pSubMenu, eMode)
+ , m_aColor(rColor)
+ {
+ }
+
+ virtual bool execute() override
+ {
+ const AutoFilterData* pData =
+ static_cast<const AutoFilterData*>(m_pSubMenu->getExtendedData());
+
+ if (!pData)
+ return false;
+
+ ScDBData* pDBData = pData->mpData;
+ if (!pDBData)
+ return false;
+
+ const ScAddress& rPos = pData->maPos;
+
+ ScViewData& rViewData = m_pSubMenu->GetViewData();
+ ScDocument& rDoc = rViewData.GetDocument();
+
+ ScQueryParam aParam;
+ pDBData->GetQueryParam(aParam);
+
+ // Try to use the existing entry for the column (if one exists).
+ ScQueryEntry* pEntry = aParam.FindEntryByField(rPos.Col(), true);
+
+ if (!pEntry)
+ {
+ // Something went terribly wrong!
+ return false;
+ }
+
+ if (ScTabViewShell::isAnyEditViewInRange(rViewData.GetViewShell(), /*bColumns*/ false, aParam.nRow1, aParam.nRow2))
+ return false;
+
+ pEntry->bDoQuery = true;
+ pEntry->nField = rPos.Col();
+ pEntry->eConnect = SC_AND;
+
+ ScFilterEntries aFilterEntries;
+ rDoc.GetFilterEntries(rPos.Col(), rPos.Row(), rPos.Tab(), aFilterEntries);
+
+ bool bActive = false;
+ auto aItem = pEntry->GetQueryItem();
+ if (aItem.maColor == m_aColor
+ && ((meMode == ScGridWindow::AutoFilterMode::TextColor
+ && aItem.meType == ScQueryEntry::ByTextColor)
+ || (meMode == ScGridWindow::AutoFilterMode::BackgroundColor
+ && aItem.meType == ScQueryEntry::ByBackgroundColor)))
+ {
+ bActive = true;
+ }
+
+ // Disable color filter when active color was selected
+ if (bActive)
+ {
+ aParam.RemoveAllEntriesByField(rPos.Col());
+ pEntry = nullptr; // invalidated by RemoveAllEntriesByField call
+
+ // tdf#46184 reset filter options to default values
+ aParam.eSearchType = utl::SearchParam::SearchType::Normal;
+ aParam.bCaseSens = false;
+ aParam.bDuplicate = true;
+ aParam.bInplace = true;
+ }
+ else
+ {
+ if (meMode == ScGridWindow::AutoFilterMode::TextColor)
+ pEntry->SetQueryByTextColor(m_aColor);
+ else
+ pEntry->SetQueryByBackgroundColor(m_aColor);
+ }
+
+ rViewData.GetView()->Query(aParam, nullptr, true);
+ pDBData->SetQueryParam(aParam);
+
+ return true;
+ }
+};
+
+class AutoFilterColorPopupStartAction : public AutoFilterSubMenuAction
+{
+public:
+ AutoFilterColorPopupStartAction(ScGridWindow* p, ScListSubMenuControl* pSubMenu, ScGridWindow::AutoFilterMode eMode)
+ : AutoFilterSubMenuAction(p, pSubMenu, eMode)
+ {
+ }
+
+ virtual bool execute() override
+ {
+ const AutoFilterData* pData =
+ static_cast<const AutoFilterData*>(m_pSubMenu->getExtendedData());
+
+ if (!pData)
+ return false;
+
+ ScDBData* pDBData = pData->mpData;
+ if (!pDBData)
+ return false;
+
+ ScViewData& rViewData = m_pSubMenu->GetViewData();
+ ScDocument& rDoc = rViewData.GetDocument();
+ const ScAddress& rPos = pData->maPos;
+
+ ScFilterEntries aFilterEntries;
+ rDoc.GetFilterEntries(rPos.Col(), rPos.Row(), rPos.Tab(), aFilterEntries);
+
+ 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());
+ PaletteManager aPaletteManager;
+ std::vector<OUString> aPaletteNames = aPaletteManager.GetPaletteList();
+ for (size_t i = 0, nLen = aPaletteNames.size(); i < nLen; ++i)
+ {
+ if (aPaletteName == aPaletteNames[i])
+ {
+ aPaletteManager.SetPalette(i);
+ xUserColorList = XPropertyList::AsColorList(
+ XPropertyList::CreatePropertyListFromURL(
+ XPropertyListType::Color, aPaletteManager.GetSelectedPalettePath()));
+ if (!xUserColorList->Load())
+ xUserColorList = nullptr;
+ break;
+ }
+ }
+
+ ScQueryParam aParam;
+ pDBData->GetQueryParam(aParam);
+ ScQueryEntry* pEntry = aParam.FindEntryByField(rPos.Col(), true);
+
+ for (auto& rColor : aColors)
+ {
+ bool bActive = false;
+
+ if (pEntry)
+ {
+ auto aItem = pEntry->GetQueryItem();
+ if (aItem.maColor == rColor
+ && ((meMode == ScGridWindow::AutoFilterMode::TextColor
+ && aItem.meType == ScQueryEntry::ByTextColor)
+ || (meMode == ScGridWindow::AutoFilterMode::BackgroundColor
+ && aItem.meType == ScQueryEntry::ByBackgroundColor)))
+ {
+ bActive = true;
+ }
+ }
+
+ 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);
+
+ 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);
+
+ 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)
+ {
+ 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();
+
+ m_pSubMenu->addMenuCheckItem(sName, bActive, *xDev,
+ new AutoFilterColorAction(mpWindow, m_pSubMenu, meMode, rColor));
+ }
+ }
+
+ m_pSubMenu->resizeToFitMenuItems();
+
+ return false;
+ }
+};
+
class AddItemToEntry
{
ScQueryEntry::QueryItemsType& mrItems;
@@ -594,7 +835,7 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
weld::Window* pPopupParent = GetFrameWeld();
int nColWidth = ScViewData::ToPixel(rDoc.GetColWidth(nCol, nTab), mrViewData.GetPPTX());
- mpAutoFilterPopup.reset(new ScCheckListMenuControl(pPopupParent, &rDoc,
+ mpAutoFilterPopup.reset(new ScCheckListMenuControl(pPopupParent, mrViewData,
aFilterEntries.mbHasDates, nColWidth, pNotifier));
int nMaxTextWidth = 0;
@@ -735,10 +976,10 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
mpAutoFilterPopup->addMenuItem(
ScResId(SCSTR_FILTER_NOTEMPTY), new AutoFilterAction(this, AutoFilterMode::NonEmpty));
mpAutoFilterPopup->addSeparator();
- mpAutoFilterPopup->addMenuItem(
- ScResId(SCSTR_FILTER_TEXT_COLOR), new AutoFilterAction(this, AutoFilterMode::TextColor), true);
- mpAutoFilterPopup->addMenuItem(
- ScResId(SCSTR_FILTER_BACKGROUND_COLOR), new AutoFilterAction(this, AutoFilterMode::BackgroundColor), true);
+ 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();
mpAutoFilterPopup->addMenuItem(
ScResId(SCSTR_STDFILTER), new AutoFilterAction(this, AutoFilterMode::Custom));
@@ -922,91 +1163,8 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
break;
case AutoFilterMode::TextColor:
case AutoFilterMode::BackgroundColor:
- {
- ScFilterEntries aFilterEntries;
- rDoc.GetFilterEntries(rPos.Col(), rPos.Row(), rPos.Tab(), aFilterEntries);
-
- weld::Window* pWindow = GetFrameWeld();
- std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pWindow, "modules/scalc/ui/colormenu.ui"));
- std::unique_ptr<weld::Menu> xColorMenu(xBuilder->weld_menu("menu"));
-
- std::set<Color> aColors = eMode == AutoFilterMode::TextColor
- ? aFilterEntries.getTextColors()
- : aFilterEntries.getBackgroundColors();
-
- sal_Int32 i = 1;
- sal_Int32 nActive = -1;
- for (auto& rColor : aColors)
- {
- if (rColor == COL_AUTO)
- {
- OUString sText = eMode == AutoFilterMode::TextColor
- ? ScResId(SCSTR_FILTER_AUTOMATIC_COLOR)
- : ScResId(SCSTR_FILTER_NO_FILL);
- xColorMenu->append_check(OUString::number(i), sText);
- }
- else
- {
- // ColorListBox::ShowPreview is similar
- ScopedVclPtr<VirtualDevice> xDev(pWindow->create_virtual_device());
- const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
- Size aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize());
- xDev->SetOutputSize(aImageSize);
- const tools::Rectangle aRect(Point(0, 0), aImageSize);
- xDev->SetFillColor(rColor);
- xDev->SetLineColor(rStyleSettings.GetDisableColor());
- xDev->DrawRect(aRect);
-
- xColorMenu->insert(-1, OUString::number(i), OUString(),
- nullptr, xDev.get(), nullptr, TRISTATE_TRUE);
- }
- auto aItem = pEntry->GetQueryItem();
- if (aItem.maColor == rColor
- && ((eMode == AutoFilterMode::TextColor
- && aItem.meType == ScQueryEntry::ByTextColor)
- || (eMode == AutoFilterMode::BackgroundColor
- && aItem.meType == ScQueryEntry::ByBackgroundColor)))
- {
- nActive = i;
- xColorMenu->set_active(OString::number(i), true);
- }
- i++;
- }
-
- sal_Int32 nSelected = mpAutoFilterPopup->ExecuteMenu(*xColorMenu);
- xColorMenu.reset();
-
- if (nSelected == 0)
- return;
-
- mpAutoFilterPopup->terminateAllPopupMenus();
-
- // Disable color filter when active color was selected
- if (nSelected == nActive)
- {
- aParam.RemoveAllEntriesByField(rPos.Col());
- pEntry = nullptr; // invalidated by RemoveAllEntriesByField call
-
- // tdf#46184 reset filter options to default values
- aParam.eSearchType = utl::SearchParam::SearchType::Normal;
- aParam.bCaseSens = false;
- aParam.bDuplicate = true;
- aParam.bInplace = true;
- }
- else
- {
- // Get selected color from set
- std::set<Color>::iterator it = aColors.begin();
- std::advance(it, nSelected - 1);
- Color selectedColor = *it;
-
- if (eMode == AutoFilterMode::TextColor)
- pEntry->SetQueryByTextColor(selectedColor);
- else
- pEntry->SetQueryByBackgroundColor(selectedColor);
- }
- }
-
+ assert(false && "should be handled by AutoFilterColorAction::execute");
+ break;
break;
default:
// We don't know how to handle this!
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
index bf9e41bd7369..a7cd96a649ba 100644
--- a/sc/source/ui/view/gridwin2.cxx
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -474,7 +474,7 @@ void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScr
pNotifier = SfxViewShell::Current();
weld::Window* pPopupParent = GetFrameWeld();
- mpDPFieldPopup.reset(new ScCheckListMenuControl(pPopupParent, &mrViewData.GetDocument(),
+ mpDPFieldPopup.reset(new ScCheckListMenuControl(pPopupParent, mrViewData,
false, -1, pNotifier));
mpDPFieldPopup->setExtendedData(std::move(pDPData));
@@ -519,7 +519,7 @@ void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScr
ScResId(STR_MENU_SORT_DESC),
new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::DESCENDING, 0, pViewShell));
- ScListSubMenuControl* pSubMenu = mpDPFieldPopup->addSubMenuItem(ScResId(STR_MENU_SORT_CUSTOM), !aUserSortNames.empty());
+ ScListSubMenuControl* pSubMenu = mpDPFieldPopup->addSubMenuItem(ScResId(STR_MENU_SORT_CUSTOM), !aUserSortNames.empty(), false);
if (pSubMenu)
{
size_t n = aUserSortNames.size();
diff --git a/sc/uiconfig/scalc/ui/filtersubdropdown.ui b/sc/uiconfig/scalc/ui/filtersubdropdown.ui
index 5785bd9d80ae..eb9d3444032c 100644
--- a/sc/uiconfig/scalc/ui/filtersubdropdown.ui
+++ b/sc/uiconfig/scalc/ui/filtersubdropdown.ui
@@ -2,14 +2,20 @@
<!-- Generated with glade 3.38.2 -->
<interface domain="sc">
<requires lib="gtk+" version="3.20"/>
- <object class="GtkTreeStore" id="liststore1">
+ <object class="GtkListStore" id="liststore1">
<columns>
- <!-- column-name text -->
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name surface -->
+ <column type="CairoSurface"/>
+ <!-- column-name text1 -->
<column type="gchararray"/>
- <!-- column-name image1 -->
- <column type="GdkPixbuf"/>
<!-- column-name id -->
<column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
</columns>
</object>
<object class="GtkPopover" id="FilterSubDropDown">
@@ -52,9 +58,10 @@
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
<child>
- <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <object class="GtkCellRendererToggle" id="cellrenderertoggle"/>
<attributes>
- <attribute name="text">0</attribute>
+ <attribute name="visible">4</attribute>
+ <attribute name="active">0</attribute>
</attributes>
</child>
</object>
@@ -62,9 +69,19 @@
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn2">
<child>
- <object class="GtkCellRendererPixbuf" id="cellrenderertext55"/>
+ <object class="GtkCellRendererPixbuf" id="cellrendererpixbuf"/>
<attributes>
- <attribute name="pixbuf">1</attribute>
+ <attribute name="surface">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext"/>
+ <attributes>
+ <attribute name="text">2</attribute>
</attributes>
</child>
</object>