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 #ifndef INCLUDED_SC_SOURCE_UI_INC_CHECKLISTMENU_HXX
11 #define INCLUDED_SC_SOURCE_UI_INC_CHECKLISTMENU_HXX
12 
13 #include <vcl/dockwin.hxx>
14 #include <vcl/timer.hxx>
15 #include <vcl/weld.hxx>
16 
17 #include <memory>
18 #include <unordered_set>
19 #include <map>
20 #include <set>
21 
22 class ScDocument;
23 
25 
26 struct ScCheckListMember;
27 
29 {
31  {
34  DAY,
35  };
36 
37  OUString maName; // node name
38  OUString maRealName;
39  bool mbVisible;
40  bool mbDate;
41  bool mbLeaf;
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 
50 
52 {
53 public:
54  static constexpr size_t MENU_NOT_SELECTED = 999;
55 
60  class Action
61  {
62  public:
63  virtual ~Action() {}
64  virtual void execute() = 0;
65  };
66 
67  struct ResultEntry
68  {
69  OUString aName;
70  bool bValid;
71  bool bDate;
72 
73  bool operator<(const ResultEntry& rhs) const
74  {
75  return aName < rhs.aName;
76  }
77 
78  bool operator == (const ResultEntry& rhs) const
79  {
80  return aName == rhs.aName &&
81  bValid == rhs.bValid &&
82  bDate == rhs.bDate;
83  }
84  };
85  typedef std::set<ResultEntry> ResultType;
86 
87  struct MenuItemData
88  {
89  bool mbEnabled:1;
90  std::shared_ptr<Action> mxAction;
92 
93  MenuItemData();
94  };
95 
100  struct ExtendedData {
101 
102  virtual ~ExtendedData() {}
103 
104  };
105 
109  struct Config
110  {
112  bool mbRTL;
113  Config();
114  };
115 
117  bool bCanHaveSubMenu, bool bTreeMode, int nWidth);
119 
120  void addMenuItem(const OUString& rText, Action* pAction);
121  void addSeparator();
122  ScCheckListMenuWindow* addSubMenuItem(const OUString& rText, bool bEnabled);
123  void resizeToFitMenuItems();
124 
125  void selectMenuItem(size_t nPos, bool bSubMenuTimer);
126  void queueLaunchSubMenu(size_t nPos, ScCheckListMenuWindow* pMenu);
127 
128  void setMemberSize(size_t n);
129  void addDateMember(const OUString& rName, double nVal, bool bVisible);
130  void addMember(const OUString& rName, bool bVisible);
131  size_t initMembers(int nMaxMemberWidth = -1);
132  void setConfig(const Config& rConfig);
133 
134  bool isAllSelected() const;
135  void getResult(ResultType& rResult);
136  void launch(const tools::Rectangle& rRect);
137  void close(bool bOK);
138 
139  void StartPopupMode(const tools::Rectangle& rRect, FloatWinPopupFlags eFlags);
140  void EndPopupMode();
141 
142  size_t getSubMenuPos(const ScCheckListMenuControl* pSubMenu);
143  void setSubMenuFocused(const ScCheckListMenuControl* pSubMenu);
144  void queueCloseSubMenu();
145  void clearSelectedMenuItem();
146 
152  void setExtendedData(std::unique_ptr<ExtendedData> p);
153 
158 
159  void GrabFocus();
160 
161  void setOKAction(Action* p);
162  void setPopupEndAction(Action* p);
163 
164  int GetTextWidth(const OUString& rsName) const;
165  int IncreaseWindowWidthToFitText(int nMaxTextWidth);
166 
167 private:
168 
169  std::vector<MenuItemData> maMenuItems;
170 
174  void prepWindow();
175  void setAllMemberState(bool bSet);
176  void selectCurrentMemberOnly(bool bSet);
177  void updateMemberParents(const weld::TreeIter* pLeaf, size_t nIdx);
178 
179  std::unique_ptr<weld::TreeIter> ShowCheckEntry(const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true);
180  void CheckEntry(std::u16string_view sName, const weld::TreeIter* pParent, bool bCheck);
181  void CheckEntry(const weld::TreeIter& rEntry, bool bCheck);
182  void GetRecursiveChecked(const weld::TreeIter* pEntry, std::unordered_set<OUString>& vOut, OUString& rLabel);
183  std::unordered_set<OUString> GetAllChecked();
184  bool IsChecked(std::u16string_view sName, const weld::TreeIter* pParent);
185  int GetCheckedEntryCount() const;
186  void CheckAllChildren(const weld::TreeIter& rEntry, bool bCheck);
187 
188  void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer);
189 
190  std::unique_ptr<weld::TreeIter> FindEntry(const weld::TreeIter* pParent, std::u16string_view sNode);
191 
192  void executeMenuItem(size_t nPos);
193 
198  void terminateAllPopupMenus();
199 
200  void endSubMenu(ScCheckListMenuControl& rSubMenu);
201 
202  struct SubMenuItemData;
203 
204  void handleMenuTimeout(const SubMenuItemData* pTimer);
205 
206  void launchSubMenu(bool bSetMenuPos);
207 
208  void CreateDropDown();
209 
210  void NotifyCloseLOK();
211 
212  DECL_LINK(ButtonHdl, weld::Button&, void);
213  DECL_LINK(TriStateHdl, weld::ToggleButton&, void);
214 
215  void Check(const weld::TreeIter* pIter);
216 
217  DECL_LINK(CheckHdl, const weld::TreeView::iter_col&, void);
218 
219  DECL_LINK(PopupModeEndHdl, FloatingWindow*, void);
220 
221  DECL_LINK(EdModifyHdl, weld::Entry&, void);
222  DECL_LINK(EdActivateHdl, weld::Entry&, bool);
223 
224  DECL_LINK(FocusHdl, weld::Widget&, void);
225  DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
226  DECL_LINK(SelectHdl, weld::TreeView&, void);
227  DECL_LINK(TreeSizeAllocHdl, const Size&, void);
228  DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
229  DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
230 
231  DECL_LINK(PostPopdownHdl, void*, void);
232 
233 private:
235  std::unique_ptr<weld::Builder> mxBuilder;
236  std::unique_ptr<weld::Container> mxContainer;
237  std::unique_ptr<weld::TreeView> mxMenu;
238  std::unique_ptr<weld::TreeIter> mxScratchIter;
239  std::unique_ptr<weld::Entry> mxEdSearch;
240  std::unique_ptr<weld::Widget> mxBox;
241  std::unique_ptr<weld::TreeView> mxListChecks;
242  std::unique_ptr<weld::TreeView> mxTreeChecks;
244 
245  std::unique_ptr<weld::CheckButton> mxChkToggleAll;
246  std::unique_ptr<weld::Button> mxBtnSelectSingle;
247  std::unique_ptr<weld::Button> mxBtnUnselectSingle;
248 
249  std::unique_ptr<weld::Box> mxButtonBox;
250  std::unique_ptr<weld::Button> mxBtnOk;
251  std::unique_ptr<weld::Button> mxBtnCancel;
252 
254 
255  std::vector<ScCheckListMember> maMembers;
256  // For Dates
257  std::map<OUString, size_t> maYearMonthMap;
258 
259  std::unique_ptr<ExtendedData> mxExtendedData;
260  std::unique_ptr<Action> mxOKAction;
261  std::unique_ptr<Action> mxPopupEndAction;
262 
267 
269 
271 
273 
276 
278  {
281  size_t mnMenuPos;
282 
283  DECL_LINK( TimeoutHdl, Timer*, void );
284 
286  void reset();
287 
288  private:
290  };
291 
294 };
295 
301 {
302 public:
303  explicit ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc,
304  bool bCanHaveSubMenu, bool bTreeMode, int nWidth = -1,
305  ScCheckListMenuWindow* pParentMenu = nullptr,
306  vcl::ILibreOfficeKitNotifier* pNotifier = nullptr);
307  virtual void dispose() override;
308  virtual ~ScCheckListMenuWindow() override;
309 
310  virtual void GetFocus() override;
311  virtual bool EventNotify(NotifyEvent& rNEvt) override;
312 
315 
316 private:
319  std::unique_ptr<ScCheckListMenuControl, o3tl::default_delete<ScCheckListMenuControl>> mxControl;
320 };
321 
322 #endif
323 
324 /* 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)
VclPtr< vcl::Window > mxBox
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
FloatWinPopupFlags
void launchSubMenu(bool bSetMenuPos)
std::unique_ptr< ExtendedData > mxExtendedData
SubMenuItemData(ScCheckListMenuControl *pParent)
void launch(const tools::Rectangle &rRect)
void addMember(const OUString &rName, bool bVisible)
ScopedVclPtr< VirtualDevice > mxDropDown
SubMenuItemData maCloseTimer
ScCheckListMenuWindow(vcl::Window *pParent, ScDocument *pDoc, bool bCanHaveSubMenu, bool bTreeMode, int nWidth=-1, ScCheckListMenuWindow *pParentMenu=nullptr, vcl::ILibreOfficeKitNotifier *pNotifier=nullptr)
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 field button, for quick access of hide-item list...
void addDateMember(const OUString &rName, double nVal, bool bVisible)
void GetRecursiveChecked(const weld::TreeIter *pEntry, std::unordered_set< OUString > &vOut, OUString &rLabel)
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