LibreOffice Module sc (master)  1
checklistmenu.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  */
9 
10 #pragma once
11 
12 #include <vcl/timer.hxx>
13 #include <vcl/virdev.hxx>
14 #include <vcl/weld.hxx>
15 
16 #include <memory>
17 #include <unordered_set>
18 #include <map>
19 #include <set>
20 
22 class ScViewData;
23 struct ScCheckListMember;
24 struct ImplSVEvent;
25 
27 {
29  {
32  DAY,
33  };
34 
35  OUString maName; // node name
36  OUString maRealName;
37  double mnValue; // number value of filter condition
38  bool mbVisible;
39  bool mbDate;
40  bool mbLeaf;
41  bool mbValue; // true if the filter condition is value
43  // To store Year and Month if the member if DAY type
44  std::vector<OUString> maDateParts;
46  std::unique_ptr<weld::TreeIter> mxParent;
47 };
48 
49 class ScCheckListMenuWindow;
51 
56 {
57 public:
58  static constexpr size_t MENU_NOT_SELECTED = 999;
59 
64  class Action
65  {
66  public:
67  virtual ~Action() {}
68  // return true to dismiss the popup
69  virtual bool execute() = 0;
70  };
71 
72  struct ResultEntry
73  {
74  OUString aName;
75  double nValue; // number value of filter condition
76  bool bValid;
77  bool bDate;
78  bool bValue; // true if the filter condition is value
79 
80  bool operator<(const ResultEntry& rhs) const
81  {
82  return aName < rhs.aName;
83  }
84 
85  bool operator == (const ResultEntry& rhs) const
86  {
87  return aName == rhs.aName &&
88  bValid == rhs.bValid &&
89  bDate == rhs.bDate &&
90  bValue == rhs.bValue &&
91  nValue == rhs.nValue;
92  }
93  };
94  typedef std::set<ResultEntry> ResultType;
95 
96  struct MenuItemData
97  {
98  bool mbEnabled:1;
99  std::shared_ptr<Action> mxAction;
100  std::unique_ptr<ScListSubMenuControl> mxSubMenuWin;
101 
102  MenuItemData();
103  };
104 
109  struct ExtendedData {
110 
111  virtual ~ExtendedData() {}
112 
113  };
114 
118  struct Config
119  {
121  bool mbRTL;
122  Config();
123  };
124 
125  ScCheckListMenuControl(weld::Widget* pParent, ScViewData& rViewData,
126  bool bTreeMode, int nWidth);
128 
129  void addMenuItem(const OUString& rText, Action* pAction);
130  void addSeparator();
131  ScListSubMenuControl* addSubMenuItem(const OUString& rText, bool bEnabled, bool bColorMenu);
132 
133  void selectMenuItem(size_t nPos, bool bSubMenuTimer);
134  void queueLaunchSubMenu(size_t nPos, ScListSubMenuControl* pMenu);
135 
136  void setMemberSize(size_t n);
137  void addDateMember(const OUString& rName, double nVal, bool bVisible);
138  void addMember(const OUString& rName, const double nVal, bool bVisible,
139  bool bValue = false);
140  size_t initMembers(int nMaxMemberWidth = -1);
141  void setConfig(const Config& rConfig);
142 
143  bool isAllSelected() const;
144  void getResult(ResultType& rResult);
145  void launch(weld::Widget* pWidget, const tools::Rectangle& rRect);
146  void close(bool bOK);
147 
148  void StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect);
149  void EndPopupMode();
150 
151  size_t getSubMenuPos(const ScListSubMenuControl* pSubMenu);
152  void setSubMenuFocused(const ScListSubMenuControl* pSubMenu);
153  void queueCloseSubMenu();
154  void clearSelectedMenuItem();
155 
161  void setExtendedData(std::unique_ptr<ExtendedData> p);
162 
167 
168  ScViewData& GetViewData() const { return mrViewData; }
169 
170  void GrabFocus();
171 
172  void setOKAction(Action* p);
173  void setPopupEndAction(Action* p);
174 
175  int GetTextWidth(const OUString& rsName) const;
176  int IncreaseWindowWidthToFitText(int nMaxTextWidth);
177 
182  void terminateAllPopupMenus();
183 
184  void endSubMenu(ScListSubMenuControl& rSubMenu);
185 private:
186 
187  std::vector<MenuItemData> maMenuItems;
188 
192  void prepWindow();
193  void setAllMemberState(bool bSet);
194  void selectCurrentMemberOnly(bool bSet);
195  void updateMemberParents(const weld::TreeIter* pLeaf, size_t nIdx);
196 
197  std::unique_ptr<weld::TreeIter> ShowCheckEntry(const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true);
198  void CheckEntry(std::u16string_view sName, const weld::TreeIter* pParent, bool bCheck);
199  void CheckEntry(const weld::TreeIter& rEntry, bool bCheck);
200  void GetRecursiveChecked(const weld::TreeIter* pEntry, std::unordered_set<OUString>& vOut, OUString& rLabel);
201  std::unordered_set<OUString> GetAllChecked();
202  bool IsChecked(std::u16string_view sName, const weld::TreeIter* pParent);
203  int GetCheckedEntryCount() const;
204  void CheckAllChildren(const weld::TreeIter& rEntry, bool bCheck);
205 
206  void setSelectedMenuItem(size_t nPos);
207 
208  std::unique_ptr<weld::TreeIter> FindEntry(const weld::TreeIter* pParent, std::u16string_view sNode);
209 
210  void executeMenuItem(size_t nPos);
211 
217 
218  struct SubMenuItemData;
219 
220  void handleMenuTimeout(const SubMenuItemData* pTimer);
221 
222  void launchSubMenu();
223 
224  void CreateDropDown();
225 
226  DECL_LINK(ButtonHdl, weld::Button&, void);
227  DECL_LINK(TriStateHdl, weld::Toggleable&, void);
228 
229  void Check(const weld::TreeIter* pIter);
230 
231  DECL_LINK(CheckHdl, const weld::TreeView::iter_col&, void);
232 
233  DECL_LINK(PopupModeEndHdl, weld::Popover&, void);
234 
235  DECL_LINK(EdModifyHdl, weld::Entry&, void);
236  DECL_LINK(EdActivateHdl, weld::Entry&, bool);
237 
238  DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
239  DECL_LINK(SelectHdl, weld::TreeView&, void);
240  DECL_LINK(TreeSizeAllocHdl, const Size&, void);
241  DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
242  DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
243  DECL_LINK(MouseEnterHdl, const MouseEvent&, bool);
244 
245  DECL_LINK(PostPopdownHdl, void*, void);
246 
247  void SetDropdownPos();
248 
249  DECL_LINK(SetDropdownPosHdl, void*, void);
250 
251  DECL_LINK(CommandHdl, const CommandEvent&, bool);
252 
253  void ResizeToRequest();
254 
255  void DropPendingEvents();
256 
257 private:
258  std::unique_ptr<weld::Builder> mxBuilder;
259  std::unique_ptr<weld::Popover> mxPopover;
260  std::unique_ptr<weld::Container> mxContainer;
261  std::unique_ptr<weld::TreeView> mxMenu;
262  std::unique_ptr<weld::TreeIter> mxScratchIter;
263  std::unique_ptr<weld::Widget> mxNonMenu;
264  std::unique_ptr<weld::Entry> mxEdSearch;
265  std::unique_ptr<weld::Widget> mxBox;
266  std::unique_ptr<weld::TreeView> mxListChecks;
267  std::unique_ptr<weld::TreeView> mxTreeChecks;
269 
270  std::unique_ptr<weld::CheckButton> mxChkToggleAll;
271  std::unique_ptr<weld::Button> mxBtnSelectSingle;
272  std::unique_ptr<weld::Button> mxBtnUnselectSingle;
273 
274  std::unique_ptr<weld::Box> mxButtonBox;
275  std::unique_ptr<weld::Button> mxBtnOk;
276  std::unique_ptr<weld::Button> mxBtnCancel;
277  std::unique_ptr<weld::Menu> mxContextMenu;
278 
280 
281  std::vector<ScCheckListMember> maMembers;
282  // For Dates
283  std::map<OUString, size_t> maYearMonthMap;
284 
285  std::unique_ptr<ExtendedData> mxExtendedData;
286  std::unique_ptr<Action> mxOKAction;
287  std::unique_ptr<Action> mxPopupEndAction;
288 
295 
297 
299 
302 
305 
307  {
310  size_t mnMenuPos;
311 
312  DECL_LINK( TimeoutHdl, Timer*, void );
313 
315  void reset();
316 
317  private:
319  };
320 
323 };
324 
326 {
327 public:
328  ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& rParentControl, bool bColorMenu);
329 
331 
332  void GrabFocus();
333  bool IsVisible() const;
334 
335  void StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect);
336  void EndPopupMode();
337 
338  void addMenuItem(const OUString& rText, ScCheckListMenuControl::Action* pAction);
339  // nMenu of 0 for background color, nMenu of 1 for text color
340  void addMenuColorItem(const OUString& rText, bool bActive, VirtualDevice& rImage,
341  int nMenu, ScCheckListMenuControl::Action* pAction);
342  void addSeparator();
343  void clearMenuItems();
344  void resizeToFitMenuItems();
345 
348  VclPtr<VirtualDevice> create_virtual_device() const { return mxMenu->create_virtual_device(); }
349 
354  void terminateAllPopupMenus();
355 
356 private:
357  std::unique_ptr<weld::Builder> mxBuilder;
358  std::unique_ptr<weld::Popover> mxPopover;
359  std::unique_ptr<weld::Container> mxContainer;
360  std::unique_ptr<weld::TreeView> mxMenu;
361  std::unique_ptr<weld::TreeView> mxBackColorMenu;
362  std::unique_ptr<weld::TreeView> mxTextColorMenu;
363  std::unique_ptr<weld::TreeIter> mxScratchIter;
364  std::unique_ptr<ScCheckListMenuControl::Action> mxPopupStartAction;
365  std::vector<ScCheckListMenuControl::MenuItemData> maMenuItems;
370 
371  DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
372  DECL_LINK(ColorSelChangedHdl, weld::TreeView&, void);
373  DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
374 
375  void SetupMenu(weld::TreeView& rMenu);
376 
379 };
380 
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::set< ResultEntry > ResultType
int mnCheckListVisibleRows
whole window width.
std::unique_ptr< weld::Builder > mxBuilder
std::unique_ptr< weld::Button > mxBtnUnselectSingle
void updateMemberParents(const weld::TreeIter *pLeaf, size_t nIdx)
void setOKAction(Action *p)
std::vector< MenuItemData > maMenuItems
void prepWindow()
Calculate the appropriate window size based on the menu items.
std::unique_ptr< weld::TreeIter > mxParent
std::unique_ptr< weld::Button > mxBtnSelectSingle
void executeMenuItem(size_t nPos)
int mnWndWidth
matching width request for mxChecks
void CheckEntry(std::u16string_view sName, const weld::TreeIter *pParent, bool bCheck)
void addMenuColorItem(const OUString &rText, bool bActive, VirtualDevice &rImage, int nMenu, ScCheckListMenuControl::Action *pAction)
std::unique_ptr< weld::TreeView > mxMenu
ImplSVEvent * mnAsyncPostPopdownId
std::unordered_set< OUString > GetAllChecked()
void selectMenuItem(size_t nPos, bool bSubMenuTimer)
This class implements a popup window for the auto filter dropdown.
std::unique_ptr< ScCheckListMenuControl::Action > mxPopupStartAction
std::unique_ptr< weld::TreeIter > FindEntry(const weld::TreeIter *pParent, std::u16string_view sNode)
void CheckAllChildren(const weld::TreeIter &rEntry, bool bCheck)
DECL_LINK(TimeoutHdl, Timer *, void)
std::unique_ptr< weld::Container > mxContainer
std::unique_ptr< weld::TreeView > mxMenu
ScListSubMenuControl * addSubMenuItem(const OUString &rText, bool bEnabled, bool bColorMenu)
void setPopupEndAction(Action *p)
Action to perform when an event takes place.
Configuration options for this popup window.
std::unique_ptr< weld::TreeIter > mxScratchIter
std::unique_ptr< weld::Widget > mxNonMenu
void StartPopupMode(weld::Widget *pParent, const tools::Rectangle &rRect)
std::unique_ptr< weld::TreeIter > ShowCheckEntry(const OUString &sName, ScCheckListMember &rMember, bool bShow=true, bool bCheck=true)
std::pair< const TreeIter &, int > iter_col
std::unique_ptr< weld::TreeView > mxTextColorMenu
void executeMenuItem(ScCheckListMenuControl::Action *pAction)
void launch(weld::Widget *pWidget, const tools::Rectangle &rRect)
void setAllMemberState(bool bSet)
std::unique_ptr< weld::TreeIter > mxScratchIter
static constexpr size_t MENU_NOT_SELECTED
void setPopupStartAction(ScCheckListMenuControl::Action *p)
bool IsChecked(std::u16string_view sName, const weld::TreeIter *pParent)
void addMenuItem(const OUString &rText, Action *pAction)
void handleMenuTimeout(const SubMenuItemData *pTimer)
bool operator<(const ResultEntry &rhs) const
SubMenuItemData maOpenTimer
std::unique_ptr< Action > mxOKAction
bool operator==(const ResultEntry &rhs) const
void getResult(ResultType &rResult)
int IncreaseWindowWidthToFitText(int nMaxTextWidth)
void addMenuItem(const OUString &rText, ScCheckListMenuControl::Action *pAction)
std::vector< OUString > maDateParts
size_t getSubMenuPos(const ScListSubMenuControl *pSubMenu)
void setMemberSize(size_t n)
std::unique_ptr< weld::TreeView > mxTreeChecks
ScCheckListMenuControl & mrParentControl
ScListSubMenuControl(weld::Widget *pParent, ScCheckListMenuControl &rParentControl, bool bColorMenu)
int GetCheckedEntryCount() const
std::shared_ptr< Action > mxAction
std::unique_ptr< weld::CheckButton > mxChkToggleAll
std::vector< ScCheckListMember > maMembers
void terminateAllPopupMenus()
Dismiss all visible popup menus and set focus back to the application window.
ScViewData & GetViewData() const
std::map< OUString, size_t > maYearMonthMap
std::unique_ptr< weld::Box > mxButtonBox
std::unique_ptr< weld::Button > mxBtnOk
size_t initMembers(int nMaxMemberWidth=-1)
void endSubMenu(ScListSubMenuControl &rSubMenu)
ExtendedData * getExtendedData()
Get the store auxiliary data, or NULL if no such data is stored.
void setExtendedData(std::unique_ptr< ExtendedData > p)
Set auxiliary data that the client code might need.
std::unique_ptr< weld::Builder > mxBuilder
ScViewData & GetViewData() const
void setConfig(const Config &rConfig)
tools::Rectangle GetSubMenuParentRect()
Get the area of the active row.
DatePartType meDatePartType
void StartPopupMode(weld::Widget *pParent, const tools::Rectangle &rRect)
std::unique_ptr< ExtendedData > mxExtendedData
SubMenuItemData(ScCheckListMenuControl *pParent)
void addMember(const OUString &rName, const double nVal, bool bVisible, bool bValue=false)
ScopedVclPtr< VirtualDevice > mxDropDown
SubMenuItemData maCloseTimer
weld::TreeView * mpChecks
std::unique_ptr< weld::Popover > mxPopover
ScCheckListMenuControl(weld::Widget *pParent, ScViewData &rViewData, bool bTreeMode, int nWidth)
int GetTextWidth(const OUString &rsName) const
std::unique_ptr< weld::Widget > mxBox
std::unique_ptr< ScListSubMenuControl > mxSubMenuWin
void terminateAllPopupMenus()
Dismiss all visible popup menus and set focus back to the application window.
void addItem(ScCheckListMenuControl::Action *pAction)
std::unique_ptr< weld::Container > mxContainer
void * p
std::unique_ptr< weld::Menu > mxContextMenu
VclPtr< VirtualDevice > create_virtual_device() const
DECL_LINK(RowActivatedHdl, weld::TreeView &rMEvt, bool)
std::unique_ptr< Action > mxPopupEndAction
void selectCurrentMemberOnly(bool bSet)
void addDateMember(const OUString &rName, double nVal, bool bVisible)
void GetRecursiveChecked(const weld::TreeIter *pEntry, std::unordered_set< OUString > &vOut, OUString &rLabel)
void setSubMenuFocused(const ScListSubMenuControl *pSubMenu)
void setSelectedMenuItem(size_t nPos)
ScCheckListMenuControl::ExtendedData * getExtendedData()
void queueLaunchSubMenu(size_t nPos, ScListSubMenuControl *pMenu)
std::unique_ptr< weld::Popover > mxPopover
TriState
std::vector< ScCheckListMenuControl::MenuItemData > maMenuItems
std::unique_ptr< weld::TreeView > mxBackColorMenu
Extended data that the client code may need to store.
std::unique_ptr< weld::TreeView > mxListChecks
DECL_LINK(ButtonHdl, weld::Button &, void)
void SetupMenu(weld::TreeView &rMenu)
ImplSVEvent * mnAsyncSetDropdownPosId
void Check(const weld::TreeIter *pIter)
std::unique_ptr< weld::Button > mxBtnCancel
std::unique_ptr< weld::Entry > mxEdSearch