Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / inc / checklistmenu.hxx
blobea9e7edfc4b73677e019c1ca0306449745e3a02d
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/scrbar.hxx>
17 #include <vcl/timer.hxx>
18 #include <svx/checklbx.hxx>
20 #include <memory>
21 #include <unordered_map>
22 #include <map>
24 namespace com { namespace sun { namespace star {
26 namespace accessibility {
27 class XAccessible;
30 }}}
32 class ScDocument;
33 class ScAccessibleFilterMenu;
35 class ScMenuFloatingWindow : public PopupMenuFloatingWindow
37 public:
38 static size_t MENU_NOT_SELECTED;
39 /**
40 * Action to perform when an event takes place. Create a sub-class of
41 * this to implement the desired action.
43 class Action
45 public:
46 virtual ~Action() {}
47 virtual void execute() = 0;
50 explicit ScMenuFloatingWindow(vcl::Window* pParent, ScDocument* pDoc, sal_uInt16 nMenuStackLevel = 0);
51 virtual ~ScMenuFloatingWindow();
52 void dispose() override;
54 virtual void PopupModeEnd() override;
55 virtual void MouseMove(const MouseEvent& rMEvt) override;
56 virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
57 virtual void MouseButtonUp(const MouseEvent& rMEvt) override;
58 virtual void KeyInput(const KeyEvent& rKEvt) override;
59 virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) override;
60 virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
62 void addMenuItem(const OUString& rText, Action* pAction);
63 void addSeparator();
65 ScMenuFloatingWindow* addSubMenuItem(const OUString& rText, bool bEnabled);
66 void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu);
67 void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer);
68 void clearSelectedMenuItem();
69 ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const;
70 bool isMenuItemSelected(size_t nPos) const;
71 size_t getSelectedMenuItem() const { return mnSelectedMenu;}
73 void setName(const OUString& rName);
74 const OUString& getName() const { return maName;}
76 void executeMenuItem(size_t nPos);
77 void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const;
78 ScMenuFloatingWindow* getParentMenuWindow() const { return mpParentMenu;}
80 protected:
81 virtual void handlePopupEnd();
83 Size getMenuSize() const;
84 void drawMenuItem(vcl::RenderContext& rRenderContext, size_t nPos);
85 void drawSeparator(vcl::RenderContext& rRenderContext, size_t nPos);
86 void drawAllMenuItems(vcl::RenderContext& rRenderContext);
87 const vcl::Font& getLabelFont() const
89 return maLabelFont;
92 void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu);
93 void queueCloseSubMenu();
94 void launchSubMenu(bool bSetMenuPos);
95 void endSubMenu(ScMenuFloatingWindow* pSubMenu);
97 void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const;
99 ScDocument* getDoc() { return mpDoc;}
101 protected:
102 css::uno::Reference<css::accessibility::XAccessible> mxAccessible;
104 private:
105 struct SubMenuItemData;
106 void handleMenuTimeout(SubMenuItemData* pTimer);
108 void resizeToFitMenuItems();
109 void highlightMenuItem(vcl::RenderContext& rRenderContext, size_t nPos, bool bSelected);
111 size_t getEnclosingMenuItem(const Point& rPos) const;
112 size_t getSubMenuPos(ScMenuFloatingWindow* pSubMenu);
115 * Fire a menu highlight event since the accessibility framework needs
116 * this to track focus on menu items.
118 void fireMenuHighlightedEvent();
121 * Make sure that the specified submenu is permanently up, the submenu
122 * close timer is not active, and the correct menu item associated with
123 * the submenu is highlighted.
125 void setSubMenuFocused(ScMenuFloatingWindow* pSubMenu);
128 * When a menu item of an invisible submenu is selected, we need to make
129 * sure that all its parent menu(s) are visible, with the right menu item
130 * highlighted in each of the parents. Calling this method ensures it.
132 void ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu);
135 * Dismiss any visible child submenus when a menu item of a parent menu is
136 * selected.
138 void ensureSubMenuNotVisible();
141 * Dismiss all visible popup menus and set focus back to the application
142 * window. This method is called e.g. when a menu action is fired.
144 void terminateAllPopupMenus();
146 private:
148 struct MenuItemData
150 OUString maText;
151 bool mbEnabled:1;
152 bool mbSeparator:1;
154 std::shared_ptr<Action> mpAction;
155 VclPtr<ScMenuFloatingWindow> mpSubMenuWin;
157 MenuItemData();
160 std::vector<MenuItemData> maMenuItems;
162 struct SubMenuItemData
164 Timer maTimer;
165 VclPtr<ScMenuFloatingWindow> mpSubMenu;
166 size_t mnMenuPos;
168 DECL_LINK_TYPED( TimeoutHdl, Timer*, void );
170 SubMenuItemData(ScMenuFloatingWindow* pParent);
171 void reset();
173 private:
174 VclPtr<ScMenuFloatingWindow> mpParent;
176 SubMenuItemData maOpenTimer;
177 SubMenuItemData maCloseTimer;
179 vcl::Font maLabelFont;
181 // Name of this menu window, taken from the menu item of the parent window
182 // that launches it (if this is a sub menu). If this is a top-level menu
183 // window, then this name can be anything.
184 OUString maName;
186 size_t mnSelectedMenu;
187 size_t mnClickedMenu;
189 ScDocument* mpDoc;
191 VclPtr<ScMenuFloatingWindow> mpParentMenu;
194 class ScCheckListMenuWindow;
196 template <class T> struct VclPtr_hash;
197 template <> struct VclPtr_hash< VclPtr<vcl::Window> >
199 size_t operator()( const VclPtr<vcl::Window>& r ) const
201 return reinterpret_cast<size_t>(r.get());
205 class ScTabStops
207 private:
208 typedef std::unordered_map< VclPtr<vcl::Window>, size_t, VclPtr_hash<VclPtr<vcl::Window>> > ControlToPosMap;
209 VclPtr<ScCheckListMenuWindow> mpMenuWindow;
210 ControlToPosMap maControlToPos;
211 std::vector<VclPtr<vcl::Window>> maControls;
212 size_t mnCurTabStop;
213 public:
214 ScTabStops( ScCheckListMenuWindow* mpMenuWin );
215 ~ScTabStops();
216 void AddTabStop( vcl::Window* pWin );
217 void SetTabStop( vcl::Window* pWin );
218 void CycleFocus( bool bReverse = false );
219 void clear();
222 struct ScCheckListMember;
224 class ScCheckListBox : public SvTreeListBox
226 SvLBoxButtonData* mpCheckButton;
227 ScTabStops* mpTabStops;
228 bool mbSeenMouseButtonDown;
229 void CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const;
230 void CheckAllChildren( SvTreeListEntry* pEntry, bool bCheck = true );
232 public:
234 ScCheckListBox( vcl::Window* pParent, WinBits nWinStyle = 0 );
235 virtual ~ScCheckListBox() { disposeOnce(); }
236 virtual void dispose() override { delete mpCheckButton; SvTreeListBox::dispose(); }
237 void Init();
238 void CheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bCheck = true );
239 void CheckEntry( SvTreeListEntry* pEntry, bool bCheck = true );
240 SvTreeListEntry* ShowCheckEntry( const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true );
241 bool IsChecked( const OUString& sName, SvTreeListEntry* pParent );
242 SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode );
243 sal_uInt16 GetCheckedEntryCount() const;
244 void ExpandChildren( SvTreeListEntry* pParent );
245 virtual void KeyInput( const KeyEvent& rKEvt ) override;
246 virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
247 virtual void MouseButtonUp(const MouseEvent& rMEvt) override;
248 void SetTabStopsContainer( ScTabStops* pTabStops ) { mpTabStops = pTabStops; }
251 class ScSearchEdit : public Edit
253 private:
254 ScTabStops* mpTabStops;
255 public:
256 ScSearchEdit(Window* pParent)
257 : Edit(pParent)
258 , mpTabStops(nullptr)
262 virtual ~ScSearchEdit() {}
264 virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
265 void SetTabStopsContainer( ScTabStops* pTabStops ) { mpTabStops = pTabStops; }
268 struct ScCheckListMember
270 enum DatePartType
272 YEAR,
273 MONTH,
274 DAY,
277 OUString maName; // node name
278 OUString maRealName;
279 bool mbVisible;
280 bool mbDate;
281 bool mbLeaf;
282 DatePartType meDatePartType;
283 // To store Year and Month if the member if DAY type
284 std::vector<OUString> maDateParts;
285 ScCheckListMember();
286 SvTreeListEntry* mpParent;
290 * This class implements a popup window for field button, for quick access
291 * of hide-item list, and possibly more stuff related to field options.
293 class ScCheckListMenuWindow : public ScMenuFloatingWindow
295 public:
296 typedef std::unordered_map<OUString, bool, OUStringHash> ResultType;
299 * Extended data that the client code may need to store. Create a
300 * sub-class of this and store data there.
302 struct ExtendedData {
304 virtual ~ExtendedData() {}
309 * Configuration options for this popup window.
311 struct Config
313 bool mbAllowEmptySet;
314 bool mbRTL;
315 Config();
318 explicit ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc);
319 virtual ~ScCheckListMenuWindow();
320 virtual void dispose() override;
322 virtual void MouseMove(const MouseEvent& rMEvt) override;
323 virtual bool Notify(NotifyEvent& rNEvt) override;
324 virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) override;
325 virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override;
327 void setMemberSize(size_t n);
328 void addDateMember(const OUString& rName, double nVal, bool bVisible);
329 void addMember(const OUString& rName, bool bVisible);
330 void initMembers();
331 void setConfig(const Config& rConfig);
333 bool isAllSelected() const;
334 void getResult(ResultType& rResult);
335 void launch(const Rectangle& rRect);
336 void close(bool bOK);
339 * Set auxiliary data that the client code might need. Note that this
340 * popup window class manages its life time; no explicit deletion of the
341 * instance is needed in the client code.
343 void setExtendedData(ExtendedData* p);
346 * Get the store auxiliary data, or NULL if no such data is stored.
348 ExtendedData* getExtendedData();
350 void setOKAction(Action* p);
351 void setPopupEndAction(Action* p);
353 protected:
354 virtual void handlePopupEnd() override;
356 private:
358 class CancelButton : public ::CancelButton
360 public:
361 CancelButton(ScCheckListMenuWindow* pParent);
362 virtual ~CancelButton();
363 virtual void dispose() override;
365 virtual void Click() override;
367 private:
368 VclPtr<ScCheckListMenuWindow> mpParent;
371 enum SectionType {
372 WHOLE, // entire window
373 LISTBOX_AREA_OUTER, // box enclosing the check box items.
374 LISTBOX_AREA_INNER, // box enclosing the check box items.
375 SINGLE_BTN_AREA, // box enclosing the single-action buttons.
376 CHECK_TOGGLE_ALL, // check box for toggling all items.
377 BTN_SINGLE_SELECT,
378 BTN_SINGLE_UNSELECT,
379 BTN_OK, // OK button
380 BTN_CANCEL, // Cancel button
381 EDIT_SEARCH, // Search box
383 void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const;
386 * Calculate the appropriate window size, the position and size of each
387 * control based on the menu items.
389 void packWindow();
390 void setAllMemberState(bool bSet);
391 void selectCurrentMemberOnly(bool bSet);
392 void updateMemberParents( SvTreeListEntry* pLeaf, size_t nIdx );
394 DECL_LINK_TYPED( ButtonHdl, Button*, void );
395 DECL_LINK_TYPED( TriStateHdl, Button*, void );
396 DECL_LINK_TYPED( CheckHdl, SvTreeListBox*, void );
397 DECL_LINK_TYPED( EdModifyHdl, Edit&, void );
399 private:
400 VclPtr<ScSearchEdit> maEdSearch;
401 VclPtr<ScCheckListBox> maChecks;
403 VclPtr<TriStateBox> maChkToggleAll;
404 VclPtr<ImageButton> maBtnSelectSingle;
405 VclPtr<ImageButton> maBtnUnselectSingle;
407 VclPtr<OKButton> maBtnOk;
408 VclPtr<CancelButton> maBtnCancel;
410 std::vector<ScCheckListMember> maMembers;
411 // For Dates
412 std::map<OUString, size_t> maYearMonthMap;
414 std::unique_ptr<ExtendedData> mpExtendedData;
415 std::unique_ptr<Action> mpOKAction;
416 std::unique_ptr<Action> mpPopupEndAction;
418 Config maConfig;
419 Size maWndSize; /// whole window size.
420 Size maMenuSize; /// size of all menu items combined.
421 TriState mePrevToggleAllState;
422 ScTabStops maTabStops;
425 #endif
427 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */