tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / inc / checklistmenu.hxx
blob558ef9f47e3793cc6a6ecbb13d7544e01a0b29a2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #pragma once
12 #include <vcl/timer.hxx>
13 #include <vcl/virdev.hxx>
14 #include <vcl/weld.hxx>
16 #include <memory>
17 #include <unordered_set>
18 #include <map>
19 #include <set>
21 class ScCheckListMenuControl;
22 class ScViewData;
23 struct ScCheckListMember;
24 struct ImplSVEvent;
26 struct ScCheckListMember
28 enum DatePartType
30 YEAR,
31 MONTH,
32 DAY,
35 OUString maName; // node name
36 OUString maRealName;
37 double mnValue; // number value of filter condition
38 bool mbVisible;
39 bool mbMarked;
40 bool mbCheck;
41 bool mbHiddenByOtherFilter;
42 bool mbDate;
43 bool mbLeaf;
44 bool mbValue; // true if the filter condition is value
45 DatePartType meDatePartType;
46 // To store Year and Month if the member if DAY type
47 std::vector<OUString> maDateParts;
48 ScCheckListMember();
49 std::unique_ptr<weld::TreeIter> mxParent;
52 class ScCheckListMenuWindow;
53 class ScListSubMenuControl;
55 /**
56 * This class implements a popup window for the auto filter dropdown.
58 class ScCheckListMenuControl final
60 public:
61 static constexpr size_t MENU_NOT_SELECTED = 999;
63 /**
64 * Action to perform when an event takes place. Create a sub-class of
65 * this to implement the desired action.
67 class Action
69 public:
70 virtual ~Action() {}
71 // return true to dismiss the popup
72 virtual bool execute() = 0;
75 struct ResultEntry
77 OUString aName;
78 double nValue; // number value of filter condition
79 bool bValid;
80 bool bDate;
81 bool bValue; // true if the filter condition is value
83 bool operator<(const ResultEntry& rhs) const
85 return aName < rhs.aName;
88 bool operator == (const ResultEntry& rhs) const
90 return aName == rhs.aName &&
91 bValid == rhs.bValid &&
92 bDate == rhs.bDate &&
93 bValue == rhs.bValue &&
94 nValue == rhs.nValue;
97 typedef std::set<ResultEntry> ResultType;
100 enum RestoreFocus
102 Menu,
103 EdSearch,
104 Checks,
105 ChkToggleAll,
106 ChkLockChecked,
107 BtnSelectSingle,
108 BtnUnselectSingle
111 struct MenuItemData
113 bool mbEnabled:1;
114 std::shared_ptr<Action> mxAction;
115 std::unique_ptr<ScListSubMenuControl> mxSubMenuWin;
117 MenuItemData();
121 * Extended data that the client code may need to store. Create a
122 * sub-class of this and store data there.
124 struct ExtendedData {
126 virtual ~ExtendedData() {}
131 * Configuration options for this popup window.
133 struct Config
135 bool mbAllowEmptySet;
136 bool mbRTL;
137 Config();
140 ScCheckListMenuControl(weld::Widget* pParent, ScViewData& rViewData,
141 bool bTreeMode, int nWidth, bool bIsMultiField = false);
142 ~ScCheckListMenuControl();
144 void addMenuItem(const OUString& rText, Action* pAction);
145 void addSeparator();
146 ScListSubMenuControl* addSubMenuItem(const OUString& rText, bool bEnabled, bool bColorMenu);
148 void selectMenuItem(size_t nPos, bool bSubMenuTimer);
149 void queueLaunchSubMenu(size_t nPos, ScListSubMenuControl* pMenu);
151 void setMemberSize(size_t n);
152 void addDateMember(const OUString& rName, double nVal, bool bVisible, bool bHiddenByOtherFilter);
153 void addMember(const OUString& rName, const double nVal, bool bVisible, bool bHiddenByOtherFilter,
154 bool bValue = false);
155 void clearMembers();
156 size_t initMembers(int nMaxMemberWidth = -1, bool bUnlock=false);
157 void setConfig(const Config& rConfig);
159 bool isAllSelected() const;
160 void getResult(ResultType& rResult);
161 void launch(weld::Widget* pWidget, const tools::Rectangle& rRect);
162 void close(bool bOK);
164 void StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect);
165 void EndPopupMode();
167 size_t getSubMenuPos(const ScListSubMenuControl* pSubMenu);
168 void setSubMenuFocused(const ScListSubMenuControl* pSubMenu);
169 void queueCloseSubMenu();
170 void clearSelectedMenuItem();
173 * Set auxiliary data that the client code might need. Note that this
174 * popup window class manages its life time; no explicit deletion of the
175 * instance is needed in the client code.
177 void setExtendedData(std::unique_ptr<ExtendedData> p);
180 * Get the store auxiliary data, or NULL if no such data is stored.
182 ExtendedData* getExtendedData();
184 ScViewData& GetViewData() const { return mrViewData; }
186 void GrabFocus();
188 void setOKAction(Action* p);
189 void setPopupEndAction(Action* p);
190 void setFieldChangedAction(Action* p);
192 int GetTextWidth(const OUString& rsName) const;
193 int IncreaseWindowWidthToFitText(int nMaxTextWidth);
196 * Dismiss all visible popup menus and set focus back to the application
197 * window. This method is called e.g. when a menu action is fired.
199 void terminateAllPopupMenus();
201 void endSubMenu(ScListSubMenuControl& rSubMenu);
203 void addFields(const std::vector<OUString>& aFields);
204 tools::Long getField();
206 void SetRestoreFocus(RestoreFocus eFocus)
208 meRestoreFocus = eFocus;
210 private:
212 std::vector<MenuItemData> maMenuItems;
215 * Calculate the appropriate window size based on the menu items.
217 void prepWindow();
218 void setAllMemberState(bool bSet);
219 void selectCurrentMemberOnly(bool bSet);
220 void updateMemberParents(const weld::TreeIter* pLeaf, size_t nIdx);
222 std::unique_ptr<weld::TreeIter> ShowCheckEntry(const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true);
223 void CheckEntry(std::u16string_view sName, const weld::TreeIter* pParent, bool bCheck);
224 void CheckEntry(const weld::TreeIter& rEntry, bool bCheck);
225 void GetRecursiveChecked(const weld::TreeIter* pEntry, std::unordered_set<OUString>& vOut, OUString& rLabel);
226 std::unordered_set<OUString> GetAllChecked();
227 bool IsChecked(std::u16string_view sName, const weld::TreeIter* pParent);
228 int GetCheckedEntryCount() const;
229 void CheckAllChildren(const weld::TreeIter& rEntry, bool bCheck);
231 void setSelectedMenuItem(size_t nPos);
233 std::unique_ptr<weld::TreeIter> FindEntry(const weld::TreeIter* pParent, std::u16string_view sNode);
235 void executeMenuItem(size_t nPos);
238 * Get the area of the active row. Suitable as the parent rectangle
239 * argument for Executing a popup
241 tools::Rectangle GetSubMenuParentRect();
243 struct SubMenuItemData;
245 void handleMenuTimeout(const SubMenuItemData* pTimer);
247 void launchSubMenu();
249 void CreateDropDown();
251 DECL_LINK(ButtonHdl, weld::Button&, void);
252 DECL_LINK(TriStateHdl, weld::Toggleable&, void);
253 DECL_LINK(LockCheckedHdl, weld::Toggleable&, void);
255 void Check(const weld::TreeIter* pIter);
257 DECL_LINK(CheckHdl, const weld::TreeView::iter_col&, void);
259 DECL_LINK(PopupModeEndHdl, weld::Popover&, void);
261 DECL_LINK(SearchEditTimeoutHdl, Timer*, void);
262 DECL_LINK(ComboChangedHdl, weld::ComboBox&, void);
264 DECL_LINK(EdModifyHdl, weld::Entry&, void);
265 DECL_LINK(EdActivateHdl, weld::Entry&, bool);
267 DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
268 DECL_LINK(SelectHdl, weld::TreeView&, void);
269 DECL_LINK(TreeSizeAllocHdl, const Size&, void);
270 DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
271 DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
272 DECL_LINK(MouseEnterHdl, const MouseEvent&, bool);
274 DECL_LINK(PostPopdownHdl, void*, void);
276 void SetDropdownPos();
278 DECL_LINK(SetDropdownPosHdl, void*, void);
280 DECL_LINK(CommandHdl, const CommandEvent&, bool);
282 void ResizeToRequest();
284 void DropPendingEvents();
286 RestoreFocus DetermineRestoreFocus() const;
287 void RestorePreviousFocus();
289 private:
290 std::unique_ptr<weld::Builder> mxBuilder;
291 std::unique_ptr<weld::Popover> mxPopover;
292 std::unique_ptr<weld::Container> mxContainer;
293 std::unique_ptr<weld::TreeView> mxMenu;
294 std::unique_ptr<weld::TreeIter> mxScratchIter;
295 std::unique_ptr<weld::Widget> mxNonMenu;
296 std::unique_ptr<weld::Label> mxFieldsComboLabel;
297 std::unique_ptr<weld::ComboBox> mxFieldsCombo;
298 std::unique_ptr<weld::Entry> mxEdSearch;
299 std::unique_ptr<weld::Widget> mxBox;
300 std::unique_ptr<weld::TreeView> mxListChecks;
301 std::unique_ptr<weld::TreeView> mxTreeChecks;
302 weld::TreeView* mpChecks;
304 std::unique_ptr<weld::CheckButton> mxChkToggleAll;
305 std::unique_ptr<weld::CheckButton> mxChkLockChecked;
306 std::unique_ptr<weld::Button> mxBtnSelectSingle;
307 std::unique_ptr<weld::Button> mxBtnUnselectSingle;
309 std::unique_ptr<weld::Box> mxButtonBox;
310 std::unique_ptr<weld::Button> mxBtnOk;
311 std::unique_ptr<weld::Button> mxBtnCancel;
312 std::unique_ptr<weld::Menu> mxContextMenu;
314 ScopedVclPtr<VirtualDevice> mxDropDown;
316 std::vector<ScCheckListMember> maMembers;
317 // For Dates
318 std::map<OUString, size_t> maYearMonthMap;
320 std::unique_ptr<ExtendedData> mxExtendedData;
321 std::unique_ptr<Action> mxOKAction;
322 std::unique_ptr<Action> mxPopupEndAction;
323 std::unique_ptr<Action> mxFieldChangedAction;
325 Config maConfig;
326 Size maAllocatedSize;
327 int mnCheckWidthReq; /// matching width request for mxChecks
328 int mnWndWidth; /// whole window width.
329 int mnCheckListVisibleRows;
330 TriState mePrevToggleAllState;
332 size_t mnSelectedMenu;
334 ScViewData& mrViewData;
336 ImplSVEvent* mnAsyncPostPopdownId;
337 ImplSVEvent* mnAsyncSetDropdownPosId;
339 RestoreFocus meRestoreFocus;
341 bool mbHasDates;
342 bool mbIsPoppedUp;
344 struct SubMenuItemData
346 Timer maTimer;
347 ScListSubMenuControl* mpSubMenu;
348 size_t mnMenuPos;
350 DECL_LINK( TimeoutHdl, Timer*, void );
352 SubMenuItemData(ScCheckListMenuControl* pParent);
353 void reset();
355 private:
356 ScCheckListMenuControl* mpParent;
359 SubMenuItemData maOpenTimer;
360 SubMenuItemData maCloseTimer;
362 Timer maSearchEditTimer;
363 bool mbIsMultiField;
366 class ScListSubMenuControl final
368 public:
369 ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& rParentControl, bool bColorMenu);
371 void setPopupStartAction(ScCheckListMenuControl::Action* p);
373 void GrabFocus();
374 bool IsVisible() const;
376 void StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect);
377 void EndPopupMode();
379 void addMenuItem(const OUString& rText, ScCheckListMenuControl::Action* pAction);
380 // nMenu of 0 for background color, nMenu of 1 for text color
381 void addMenuColorItem(const OUString& rText, bool bActive, VirtualDevice& rImage,
382 int nMenu, ScCheckListMenuControl::Action* pAction);
383 void addSeparator();
384 void clearMenuItems();
385 void resizeToFitMenuItems();
387 ScViewData& GetViewData() const { return mrParentControl.GetViewData(); }
388 ScCheckListMenuControl::ExtendedData* getExtendedData() { return mrParentControl.getExtendedData(); }
389 VclPtr<VirtualDevice> create_virtual_device() const { return mxMenu->create_virtual_device(); }
392 * Dismiss all visible popup menus and set focus back to the application
393 * window. This method is called e.g. when a menu action is fired.
395 void terminateAllPopupMenus();
397 private:
398 std::unique_ptr<weld::Builder> mxBuilder;
399 std::unique_ptr<weld::Popover> mxPopover;
400 std::unique_ptr<weld::Container> mxContainer;
401 std::unique_ptr<weld::TreeView> mxMenu;
402 std::unique_ptr<weld::TreeView> mxBackColorMenu;
403 std::unique_ptr<weld::TreeView> mxTextColorMenu;
404 std::unique_ptr<weld::TreeIter> mxScratchIter;
405 std::unique_ptr<ScCheckListMenuControl::Action> mxPopupStartAction;
406 std::vector<ScCheckListMenuControl::MenuItemData> maMenuItems;
407 ScCheckListMenuControl& mrParentControl;
408 int mnBackColorMenuPrefHeight;
409 int mnTextColorMenuPrefHeight;
410 bool mbColorMenu;
412 DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
413 DECL_LINK(ColorSelChangedHdl, weld::TreeView&, void);
414 DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
416 void SetupMenu(weld::TreeView& rMenu);
418 void executeMenuItem(ScCheckListMenuControl::Action* pAction);
419 void addItem(ScCheckListMenuControl::Action* pAction);
422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */