Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / source / ui / inc / checklistmenu.hxx
blob2ff574a1525292cd526610cdf2ddb0635541f9b9
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 #ifndef INCLUDED_SC_SOURCE_UI_INC_CHECKLISTMENU_HXX
11 #define INCLUDED_SC_SOURCE_UI_INC_CHECKLISTMENU_HXX
13 #include <vcl/popupmenuwindow.hxx>
14 #include <vcl/button.hxx>
15 #include <vcl/edit.hxx>
16 #include <vcl/timer.hxx>
17 #include <vcl/svlbitm.hxx>
19 #include <memory>
20 #include <unordered_set>
21 #include <unordered_map>
22 #include <map>
23 #include <set>
25 namespace com { namespace sun { namespace star {
27 namespace accessibility {
28 class XAccessible;
31 }}}
33 class ScDocument;
34 class ScAccessibleFilterMenu;
36 class ScMenuFloatingWindow : public PopupMenuFloatingWindow
38 public:
39 static constexpr size_t MENU_NOT_SELECTED = 999;
41 /**
42 * Action to perform when an event takes place. Create a sub-class of
43 * this to implement the desired action.
45 class Action
47 public:
48 virtual ~Action() {}
49 virtual void execute() = 0;
52 explicit ScMenuFloatingWindow(vcl::Window* pParent, ScDocument* pDoc, sal_uInt16 nMenuStackLevel = 0);
53 virtual ~ScMenuFloatingWindow() override;
54 void dispose() override;
56 virtual void PopupModeEnd() override;
57 virtual void MouseMove(const MouseEvent& rMEvt) override;
58 virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
59 virtual void MouseButtonUp(const MouseEvent& rMEvt) override;
60 virtual void KeyInput(const KeyEvent& rKEvt) override;
61 virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
62 virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
64 void addMenuItem(const OUString& rText, Action* pAction);
65 void addSeparator();
67 ScMenuFloatingWindow* addSubMenuItem(const OUString& rText, bool bEnabled);
68 void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu);
69 void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer);
70 void clearSelectedMenuItem();
71 ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const;
72 bool isMenuItemSelected(size_t nPos) const;
73 size_t getSelectedMenuItem() const { return mnSelectedMenu;}
75 void setName(const OUString& rName);
76 const OUString& getName() const { return maName;}
78 void executeMenuItem(size_t nPos);
79 void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const;
80 ScMenuFloatingWindow* getParentMenuWindow() const { return mpParentMenu;}
82 protected:
83 virtual void handlePopupEnd();
85 Size getMenuSize() const;
86 void drawMenuItem(vcl::RenderContext& rRenderContext, size_t nPos);
87 void drawSeparator(vcl::RenderContext& rRenderContext, size_t nPos);
88 void drawAllMenuItems(vcl::RenderContext& rRenderContext);
89 const vcl::Font& getLabelFont() const
91 return maLabelFont;
94 void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu);
95 void queueCloseSubMenu();
96 void launchSubMenu(bool bSetMenuPos);
97 void endSubMenu(ScMenuFloatingWindow* pSubMenu);
99 void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const;
101 ScDocument* getDoc() { return mpDoc;}
103 protected:
104 css::uno::Reference<css::accessibility::XAccessible> mxAccessible;
106 private:
107 struct SubMenuItemData;
108 void handleMenuTimeout(const SubMenuItemData* pTimer);
110 void resizeToFitMenuItems();
111 void highlightMenuItem(vcl::RenderContext& rRenderContext, size_t nPos, bool bSelected);
113 size_t getEnclosingMenuItem(const Point& rPos) const;
114 size_t getSubMenuPos(const ScMenuFloatingWindow* pSubMenu);
117 * Fire a menu highlight event since the accessibility framework needs
118 * this to track focus on menu items.
120 void fireMenuHighlightedEvent();
123 * Make sure that the specified submenu is permanently up, the submenu
124 * close timer is not active, and the correct menu item associated with
125 * the submenu is highlighted.
127 void setSubMenuFocused(const ScMenuFloatingWindow* pSubMenu);
130 * When a menu item of an invisible submenu is selected, we need to make
131 * sure that all its parent menu(s) are visible, with the right menu item
132 * highlighted in each of the parents. Calling this method ensures it.
134 void ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu);
137 * Dismiss any visible child submenus when a menu item of a parent menu is
138 * selected.
140 void ensureSubMenuNotVisible();
143 * Dismiss all visible popup menus and set focus back to the application
144 * window. This method is called e.g. when a menu action is fired.
146 void terminateAllPopupMenus();
148 private:
150 struct MenuItemData
152 OUString maText;
153 bool mbEnabled:1;
154 bool mbSeparator:1;
156 std::shared_ptr<Action> mpAction;
157 VclPtr<ScMenuFloatingWindow> mpSubMenuWin;
159 MenuItemData();
162 std::vector<MenuItemData> maMenuItems;
164 struct SubMenuItemData
166 Timer maTimer;
167 VclPtr<ScMenuFloatingWindow> mpSubMenu;
168 size_t mnMenuPos;
170 DECL_LINK( TimeoutHdl, Timer*, void );
172 SubMenuItemData(ScMenuFloatingWindow* pParent);
173 void reset();
175 private:
176 VclPtr<ScMenuFloatingWindow> mpParent;
178 SubMenuItemData maOpenTimer;
179 SubMenuItemData maCloseTimer;
181 vcl::Font maLabelFont;
183 // Name of this menu window, taken from the menu item of the parent window
184 // that launches it (if this is a sub menu). If this is a top-level menu
185 // window, then this name can be anything.
186 OUString maName;
188 size_t mnSelectedMenu;
189 size_t mnClickedMenu;
191 ScDocument* mpDoc;
193 VclPtr<ScMenuFloatingWindow> mpParentMenu;
196 class ScCheckListMenuWindow;
198 template <class T> struct VclPtr_hash;
199 template <> struct VclPtr_hash< VclPtr<vcl::Window> >
201 size_t operator()( const VclPtr<vcl::Window>& r ) const
203 return reinterpret_cast<size_t>(r.get());
207 class ScTabStops
209 private:
210 typedef std::unordered_map< VclPtr<vcl::Window>, size_t, VclPtr_hash<VclPtr<vcl::Window>> > ControlToPosMap;
211 VclPtr<ScCheckListMenuWindow> mpMenuWindow;
212 ControlToPosMap maControlToPos;
213 std::vector<VclPtr<vcl::Window>> maControls;
214 size_t mnCurTabStop;
215 public:
216 ScTabStops( ScCheckListMenuWindow* mpMenuWin );
217 ~ScTabStops();
218 void AddTabStop( vcl::Window* pWin );
219 void SetTabStop( vcl::Window* pWin );
220 void CycleFocus( bool bReverse = false );
221 void clear();
224 struct ScCheckListMember;
226 class ScCheckListBox : public SvTreeListBox
228 std::unique_ptr<SvLBoxButtonData> mpCheckButton;
229 ScTabStops* mpTabStops;
230 bool mbSeenMouseButtonDown;
231 void CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const;
232 void CheckAllChildren( SvTreeListEntry* pEntry, bool bCheck );
234 public:
236 ScCheckListBox( vcl::Window* pParent );
237 virtual ~ScCheckListBox() override { disposeOnce(); }
238 virtual void dispose() override { mpCheckButton.reset(); SvTreeListBox::dispose(); }
239 void Init();
240 void CheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bCheck );
241 void CheckEntry( SvTreeListEntry* pEntry, bool bCheck );
242 SvTreeListEntry* ShowCheckEntry( const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true );
243 void GetRecursiveChecked( SvTreeListEntry* pEntry, std::unordered_set<OUString>& vOut, OUString& rLabel );
244 std::unordered_set<OUString> GetAllChecked();
245 bool IsChecked( const OUString& sName, SvTreeListEntry* pParent );
246 SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode );
247 sal_uInt16 GetCheckedEntryCount() const;
248 virtual void KeyInput( const KeyEvent& rKEvt ) override;
249 virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
250 virtual void MouseButtonUp(const MouseEvent& rMEvt) override;
251 void SetTabStopsContainer( ScTabStops* pTabStops ) { mpTabStops = pTabStops; }
254 class ScSearchEdit : public Edit
256 private:
257 ScTabStops* mpTabStops;
258 public:
259 ScSearchEdit(Window* pParent)
260 : Edit(pParent)
261 , mpTabStops(nullptr)
263 set_id("search_edit");
266 virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
267 void SetTabStopsContainer( ScTabStops* pTabStops ) { mpTabStops = pTabStops; }
270 struct ScCheckListMember
272 enum DatePartType
274 YEAR,
275 MONTH,
276 DAY,
279 OUString maName; // node name
280 OUString maRealName;
281 bool mbVisible;
282 bool mbDate;
283 bool mbLeaf;
284 DatePartType meDatePartType;
285 // To store Year and Month if the member if DAY type
286 std::vector<OUString> maDateParts;
287 ScCheckListMember();
288 SvTreeListEntry* mpParent;
292 * This class implements a popup window for field button, for quick access
293 * of hide-item list, and possibly more stuff related to field options.
295 class ScCheckListMenuWindow : public ScMenuFloatingWindow
297 public:
298 struct ResultEntry
300 OUString aName;
301 bool bValid;
302 bool bDate;
304 bool operator<(const ResultEntry& rhs) const
306 return aName < rhs.aName;
309 bool operator == (const ResultEntry& rhs) const
311 return aName == rhs.aName &&
312 bValid == rhs.bValid &&
313 bDate == rhs.bDate;
316 typedef std::set<ResultEntry> ResultType;
319 * Extended data that the client code may need to store. Create a
320 * sub-class of this and store data there.
322 struct ExtendedData {
324 virtual ~ExtendedData() {}
329 * Configuration options for this popup window.
331 struct Config
333 bool mbAllowEmptySet;
334 bool mbRTL;
335 Config();
338 explicit ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc, int nWidth = -1);
339 virtual ~ScCheckListMenuWindow() override;
340 virtual void dispose() override;
342 virtual void MouseMove(const MouseEvent& rMEvt) override;
343 virtual bool EventNotify(NotifyEvent& rNEvt) override;
344 virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
345 virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override;
347 void setMemberSize(size_t n);
348 void setHasDates(bool bHasDates);
349 void addDateMember(const OUString& rName, double nVal, bool bVisible);
350 void addMember(const OUString& rName, bool bVisible);
351 void initMembers();
352 void setConfig(const Config& rConfig);
354 bool isAllSelected() const;
355 void getResult(ResultType& rResult);
356 void launch(const tools::Rectangle& rRect);
357 void close(bool bOK);
360 * Set auxiliary data that the client code might need. Note that this
361 * popup window class manages its life time; no explicit deletion of the
362 * instance is needed in the client code.
364 void setExtendedData(std::unique_ptr<ExtendedData> p);
367 * Get the store auxiliary data, or NULL if no such data is stored.
369 ExtendedData* getExtendedData();
371 void setOKAction(Action* p);
372 void setPopupEndAction(Action* p);
374 protected:
375 virtual void handlePopupEnd() override;
377 private:
379 class CancelButton : public ::CancelButton
381 public:
382 CancelButton(ScCheckListMenuWindow* pParent);
383 virtual ~CancelButton() override;
384 virtual void dispose() override;
386 virtual void Click() override;
388 private:
389 VclPtr<ScCheckListMenuWindow> mpParent;
392 enum SectionType {
393 WHOLE, // entire window
394 LISTBOX_AREA_OUTER, // box enclosing the check box items.
395 LISTBOX_AREA_INNER, // box enclosing the check box items.
396 SINGLE_BTN_AREA, // box enclosing the single-action buttons.
397 CHECK_TOGGLE_ALL, // check box for toggling all items.
398 BTN_SINGLE_SELECT,
399 BTN_SINGLE_UNSELECT,
400 BTN_OK, // OK button
401 BTN_CANCEL, // Cancel button
402 EDIT_SEARCH, // Search box
404 void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const;
407 * Calculate the appropriate window size, the position and size of each
408 * control based on the menu items.
410 void packWindow();
411 void setAllMemberState(bool bSet);
412 void selectCurrentMemberOnly(bool bSet);
413 void updateMemberParents( const SvTreeListEntry* pLeaf, size_t nIdx );
415 DECL_LINK( ButtonHdl, Button*, void );
416 DECL_LINK( TriStateHdl, Button*, void );
417 DECL_LINK( CheckHdl, SvTreeListBox*, void );
418 DECL_LINK( EdModifyHdl, Edit&, void );
420 private:
421 VclPtr<ScSearchEdit> maEdSearch;
422 VclPtr<ScCheckListBox> maChecks;
424 VclPtr<TriStateBox> maChkToggleAll;
425 VclPtr<ImageButton> maBtnSelectSingle;
426 VclPtr<ImageButton> maBtnUnselectSingle;
428 VclPtr<OKButton> maBtnOk;
429 VclPtr<CancelButton> maBtnCancel;
431 std::vector<ScCheckListMember> maMembers;
432 // For Dates
433 std::map<OUString, size_t> maYearMonthMap;
435 std::unique_ptr<ExtendedData> mpExtendedData;
436 std::unique_ptr<Action> mpOKAction;
437 std::unique_ptr<Action> mpPopupEndAction;
439 Config maConfig;
440 Size maWndSize; /// whole window size.
441 Size maMenuSize; /// size of all menu items combined.
442 TriState mePrevToggleAllState;
443 ScTabStops maTabStops;
446 #endif
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */