From 29145df0977baa866e7da94d1d385b772ae1e6ce Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Mon, 29 Nov 2021 12:55:38 +0000 Subject: Resolves: tdf#144811 use the hover-style menu for color submenus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8653c36d084f9df5a4d34baf7d88e2f2b5f1609b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126209 Tested-by: Jenkins Reviewed-by: Caolán McNamara --- sc/source/ui/cctrl/checklistmenu.cxx | 74 +++++-- sc/source/ui/inc/checklistmenu.hxx | 28 ++- sc/source/ui/view/gridwin.cxx | 344 ++++++++++++++++++++++-------- sc/source/ui/view/gridwin2.cxx | 4 +- sc/uiconfig/scalc/ui/filtersubdropdown.ui | 33 ++- 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 #include +#include +#include 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(), 1); + mxMenu->set_image(mxMenu->n_children() - 1, css::uno::Reference(), 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 #include +#include #include #include @@ -18,10 +19,8 @@ #include #include -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 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 mxContainer; std::unique_ptr mxMenu; std::unique_ptr mxScratchIter; + std::unique_ptr mxPopupStartAction; std::vector 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 #include #include -#include +#include #include +#include #include #include +#include #include -#include #include #include #include @@ -48,8 +49,8 @@ #include #include +#include #include -#include #include #include #include @@ -127,6 +128,9 @@ #include #include +#include + +#include #include #include #include @@ -495,6 +499,7 @@ struct AutoFilterData : public ScCheckListMenuControl::ExtendedData class AutoFilterAction : public ScCheckListMenuControl::Action { +protected: VclPtr 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(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(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 aColors = meMode == ScGridWindow::AutoFilterMode::TextColor + ? aFilterEntries.getTextColors() + : aFilterEntries.getBackgroundColors(); + + XColorListRef xUserColorList; + + OUString aPaletteName(officecfg::Office::Common::UserColors::PaletteName::get()); + PaletteManager aPaletteManager; + std::vector 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 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 xBuilder(Application::CreateBuilder(pWindow, "modules/scalc/ui/colormenu.ui")); - std::unique_ptr xColorMenu(xBuilder->weld_menu("menu")); - - std::set 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 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::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 @@ - + - + + + + + - - + + + + @@ -52,9 +58,10 @@ - + - 0 + 4 + 0 @@ -62,9 +69,19 @@ - + - 1 + 1 + + + + + + + + + + 2 -- cgit