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/dockwin.hxx>
13 #include <vcl/timer.hxx>
14 #include <vcl/weld.hxx>
15 
16 #include <memory>
17 #include <unordered_set>
18 #include <map>
19 #include <set>
20 
21 class ScDocument;
22 
24 
25 struct ScCheckListMember;
26 
28 {
30  {
33  DAY,
34  };
35 
36  OUString maName; // node name
37  OUString maRealName;
38  double mnValue; // number value of filter condition
39  bool mbVisible;
40  bool mbDate;
41  bool mbLeaf;
42  bool mbValue; // true if the filter condition is value
44  // To store Year and Month if the member if DAY type
45  std::vector<OUString> maDateParts;
47  std::unique_ptr<weld::TreeIter> mxParent;
48 };
49 
51 
53 {
54 public:
55  static constexpr size_t MENU_NOT_SELECTED = 999;
56 
61  class Action
62  {
63  public:
64  virtual ~Action() {}
65  virtual void execute() = 0;
66  };
67 
68  struct ResultEntry
69  {
70  OUString aName;
71  double nValue; // number value of filter condition
72  bool bValid;
73  bool bDate;
74  bool bValue; // true if the filter condition is value
75 
76  bool operator<(const ResultEntry& rhs) const
77  {
78  return aName < rhs.aName;
79  }
80 
81  bool operator == (const ResultEntry& rhs) const
82  {
83  return aName == rhs.aName &&
84  bValid == rhs.bValid &&
85  bDate == rhs.bDate &&
86  bValue == rhs.bValue &&
87  nValue == rhs.nValue;
88  }
89  };
90  typedef std::set<ResultEntry> ResultType;
91 
92  struct MenuItemData
93  {
94  bool mbEnabled:1;
95  std::shared_ptr<Action> mxAction;
97 
98  MenuItemData();
99  };
100 
105  struct ExtendedData {
106 
107  virtual ~ExtendedData() {}
108 
109  };
110 
114  struct Config
115  {
117  bool mbRTL;
118  Config();
119  };
120 
122  bool bCanHaveSubMenu, bool bTreeMode, int nWidth);
124 
125  void addMenuItem(const OUString& rText, Action* pAction);
126  void addSeparator();
127  ScCheckListMenuWindow* addSubMenuItem(const OUString& rText, bool bEnabled);
128  void resizeToFitMenuItems();
129 
130  void selectMenuItem(size_t nPos, bool bSubMenuTimer);
131  void queueLaunchSubMenu(size_t nPos, ScCheckListMenuWindow* pMenu);
132 
133  void setMemberSize(size_t n);
134  void addDateMember(const OUString& rName, double nVal, bool bVisible);
135  void addMember(const OUString& rName, const double nVal, bool bVisible,
136  bool bValue = false);
137  size_t initMembers(int nMaxMemberWidth = -1);
138  void setConfig(const Config& rConfig);
139 
140  bool isAllSelected() const;
141  void getResult(ResultType& rResult);
142  void launch(const tools::Rectangle& rRect);
143  void close(bool bOK);
144 
145  void StartPopupMode(const tools::Rectangle& rRect, FloatWinPopupFlags eFlags);
146  void EndPopupMode();
147 
148  size_t getSubMenuPos(const ScCheckListMenuControl* pSubMenu);
149  void setSubMenuFocused(const ScCheckListMenuControl* pSubMenu);
150  void queueCloseSubMenu();
151  void clearSelectedMenuItem();
152 
158  void setExtendedData(std::unique_ptr<ExtendedData> p);
159 
164 
165  void GrabFocus();
166 
167  void setOKAction(Action* p);
168  void setPopupEndAction(Action* p);
169 
170  int GetTextWidth(const OUString& rsName) const;
171  int IncreaseWindowWidthToFitText(int nMaxTextWidth);
172 
177  void terminateAllPopupMenus();
178 
179 private:
180 
181  std::vector<MenuItemData> maMenuItems;
182 
186  void prepWindow();
187  void setAllMemberState(bool bSet);
188  void selectCurrentMemberOnly(bool bSet);
189  void updateMemberParents(const weld::TreeIter* pLeaf, size_t nIdx);
190 
191  std::unique_ptr<weld::TreeIter> ShowCheckEntry(const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true);
192  void CheckEntry(std::u16string_view sName, const weld::TreeIter* pParent, bool bCheck);
193  void CheckEntry(const weld::TreeIter& rEntry, bool bCheck);
194  void GetRecursiveChecked(const weld::TreeIter* pEntry, std::unordered_set<OUString>& vOut, OUString& rLabel);
195  std::unordered_set<OUString> GetAllChecked();
196  bool IsChecked(std::u16string_view sName, const weld::TreeIter* pParent);
197  int GetCheckedEntryCount() const;
198  void CheckAllChildren(const weld::TreeIter& rEntry, bool bCheck);
199 
200  void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer);
201 
202  std::unique_ptr<weld::TreeIter> FindEntry(const weld::TreeIter* pParent, std::u16string_view sNode);
203 
204  void executeMenuItem(size_t nPos);
205 
206  void endSubMenu(ScCheckListMenuControl& rSubMenu);
207 
208  struct SubMenuItemData;
209 
210  void handleMenuTimeout(const SubMenuItemData* pTimer);
211 
212  void launchSubMenu(bool bSetMenuPos);
213 
214  void CreateDropDown();
215 
216  void NotifyCloseLOK();
217 
218  DECL_LINK(ButtonHdl, weld::Button&, void);
219  DECL_LINK(TriStateHdl, weld::Toggleable&, void);
220 
221  void Check(const weld::TreeIter* pIter);
222 
223  DECL_LINK(CheckHdl, const weld::TreeView::iter_col&, void);
224 
225  DECL_LINK(PopupModeEndHdl, FloatingWindow*, void);
226 
227  DECL_LINK(EdModifyHdl, weld::Entry&, void);
228  DECL_LINK(EdActivateHdl, weld::Entry&, bool);
229 
230  DECL_LINK(FocusHdl, weld::Widget&, void);
231  DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
232  DECL_LINK(SelectHdl, weld::TreeView&, void);
233  DECL_LINK(TreeSizeAllocHdl, const Size&, void);
234  DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
235  DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
236 
237  DECL_LINK(PostPopdownHdl, void*, void);
238 
239 private:
241  std::unique_ptr<weld::Builder> mxBuilder;
242  std::unique_ptr<weld::Container> mxContainer;
243  std::unique_ptr<weld::TreeView> mxMenu;
244  std::unique_ptr<weld::TreeIter> mxScratchIter;
245  std::unique_ptr<weld::Entry> mxEdSearch;
246  std::unique_ptr<weld::Widget> mxBox;
247  std::unique_ptr<weld::TreeView> mxListChecks;
248  std::unique_ptr<weld::TreeView> mxTreeChecks;
250 
251  std::unique_ptr<weld::CheckButton> mxChkToggleAll;
252  std::unique_ptr<weld::Button> mxBtnSelectSingle;
253  std::unique_ptr<weld::Button> mxBtnUnselectSingle;
254 
255  std::unique_ptr<weld::Box> mxButtonBox;
256  std::unique_ptr<weld::Button> mxBtnOk;
257  std::unique_ptr<weld::Button> mxBtnCancel;
258 
260 
261  std::vector<ScCheckListMember> maMembers;
262  // For Dates
263  std::map<OUString, size_t> maYearMonthMap;
264 
265  std::unique_ptr<ExtendedData> mxExtendedData;
266  std::unique_ptr<Action> mxOKAction;
267  std::unique_ptr<Action> mxPopupEndAction;
268 
273 
275 
277 
279 
282 
284  {
287  size_t mnMenuPos;
288 
289  DECL_LINK( TimeoutHdl, Timer*, void );
290 
292  void reset();
293 
294  private:
296  };
297 
300 };
301 
306 {
307 public:
308  explicit ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc,
309  bool bCanHaveSubMenu, bool bTreeMode, int nWidth = -1,
310  ScCheckListMenuWindow* pParentMenu = nullptr,
311  const vcl::ILibreOfficeKitNotifier* pNotifier = nullptr);
312  virtual void dispose() override;
313  virtual ~ScCheckListMenuWindow() override;
314 
315  virtual void GetFocus() override;
316  virtual bool EventNotify(NotifyEvent& rNEvt) override;
317 
320 
321 private:
323  std::unique_ptr<ScCheckListMenuControl, o3tl::default_delete<ScCheckListMenuControl>> mxControl;
324 };
325 
326 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::set< ResultEntry > ResultType
std::unique_ptr< weld::Builder > mxBuilder
std::unique_ptr< weld::Button > mxBtnUnselectSingle
VclPtr< ScCheckListMenuWindow > mxParentMenu
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)
VclPtr< ScCheckListMenuWindow > mxFrame
std::unique_ptr< weld::TreeView > mxMenu
virtual ~ScCheckListMenuWindow() override
ImplSVEvent * mnAsyncPostPopdownId
void queueLaunchSubMenu(size_t nPos, ScCheckListMenuWindow *pMenu)
std::unordered_set< OUString > GetAllChecked()
ScCheckListMenuWindow * GetParentMenu()
void selectMenuItem(size_t nPos, bool bSubMenuTimer)
FloatWinPopupFlags
void StartPopupMode(const tools::Rectangle &rRect, FloatWinPopupFlags eFlags)
std::unique_ptr< weld::TreeIter > FindEntry(const weld::TreeIter *pParent, std::u16string_view sNode)
TriState mePrevToggleAllState
whole window width.
void CheckAllChildren(const weld::TreeIter &rEntry, bool bCheck)
DECL_LINK(TimeoutHdl, Timer *, void)
void setPopupEndAction(Action *p)
Action to perform when an event takes place.
Configuration options for this popup window.
std::unique_ptr< weld::TreeIter > mxScratchIter
ScCheckListMenuControl(ScCheckListMenuWindow *pParent, vcl::Window *pContainer, ScDocument *pDoc, bool bCanHaveSubMenu, bool bTreeMode, int nWidth)
std::unique_ptr< weld::TreeIter > ShowCheckEntry(const OUString &sName, ScCheckListMember &rMember, bool bShow=true, bool bCheck=true)
std::pair< const TreeIter &, int > iter_col
VclPtr< ScCheckListMenuWindow > mpSubMenu
void setAllMemberState(bool bSet)
static constexpr size_t MENU_NOT_SELECTED
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)
std::vector< OUString > maDateParts
void setMemberSize(size_t n)
std::unique_ptr< weld::TreeView > mxTreeChecks
VclPtr< ScCheckListMenuWindow > mxSubMenuWin
int GetCheckedEntryCount() const
std::shared_ptr< Action > mxAction
std::unique_ptr< weld::CheckButton > mxChkToggleAll
std::vector< ScCheckListMember > maMembers
void setSubMenuFocused(const ScCheckListMenuControl *pSubMenu)
std::map< OUString, size_t > maYearMonthMap
std::unique_ptr< weld::Box > mxButtonBox
std::unique_ptr< weld::Button > mxBtnOk
size_t initMembers(int nMaxMemberWidth=-1)
virtual void GetFocus() override
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.
virtual void dispose() override
ScCheckListMenuWindow * addSubMenuItem(const OUString &rText, bool bEnabled)
void endSubMenu(ScCheckListMenuControl &rSubMenu)
void setConfig(const Config &rConfig)
DatePartType meDatePartType
void launchSubMenu(bool bSetMenuPos)
std::unique_ptr< ExtendedData > mxExtendedData
SubMenuItemData(ScCheckListMenuControl *pParent)
void launch(const tools::Rectangle &rRect)
void addMember(const OUString &rName, const double nVal, bool bVisible, bool bValue=false)
ScopedVclPtr< VirtualDevice > mxDropDown
SubMenuItemData maCloseTimer
weld::TreeView * mpChecks
int GetTextWidth(const OUString &rsName) const
std::unique_ptr< weld::Widget > mxBox
void terminateAllPopupMenus()
Dismiss all visible popup menus and set focus back to the application window.
std::unique_ptr< weld::Container > mxContainer
ScCheckListMenuControl & get_widget()
std::unique_ptr< Action > mxPopupEndAction
void selectCurrentMemberOnly(bool bSet)
This class implements a popup window for the auto filter dropdown.
void addDateMember(const OUString &rName, double nVal, bool bVisible)
void GetRecursiveChecked(const weld::TreeIter *pEntry, std::unordered_set< OUString > &vOut, OUString &rLabel)
ScCheckListMenuWindow(vcl::Window *pParent, ScDocument *pDoc, bool bCanHaveSubMenu, bool bTreeMode, int nWidth=-1, ScCheckListMenuWindow *pParentMenu=nullptr, const vcl::ILibreOfficeKitNotifier *pNotifier=nullptr)
std::unique_ptr< ScCheckListMenuControl, o3tl::default_delete< ScCheckListMenuControl > > mxControl
TriState
void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer)
Extended data that the client code may need to store.
std::unique_ptr< weld::TreeView > mxListChecks
DECL_LINK(ButtonHdl, weld::Button &, void)
void Check(const weld::TreeIter *pIter)
std::unique_ptr< weld::Button > mxBtnCancel
std::unique_ptr< weld::Entry > mxEdSearch
size_t getSubMenuPos(const ScCheckListMenuControl *pSubMenu)
virtual bool EventNotify(NotifyEvent &rNEvt) override