1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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>
20 #include <unordered_set>
21 #include <unordered_map>
25 namespace com
{ namespace sun
{ namespace star
{
27 namespace accessibility
{
34 class ScAccessibleFilterMenu
;
36 class ScMenuFloatingWindow
: public PopupMenuFloatingWindow
39 static constexpr size_t MENU_NOT_SELECTED
= 999;
42 * Action to perform when an event takes place. Create a sub-class of
43 * this to implement the desired 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
);
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
;}
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
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
;}
104 css::uno::Reference
<css::accessibility::XAccessible
> mxAccessible
;
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
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();
156 std::shared_ptr
<Action
> mpAction
;
157 VclPtr
<ScMenuFloatingWindow
> mpSubMenuWin
;
162 std::vector
<MenuItemData
> maMenuItems
;
164 struct SubMenuItemData
167 VclPtr
<ScMenuFloatingWindow
> mpSubMenu
;
170 DECL_LINK( TimeoutHdl
, Timer
*, void );
172 SubMenuItemData(ScMenuFloatingWindow
* pParent
);
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.
188 size_t mnSelectedMenu
;
189 size_t mnClickedMenu
;
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());
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
;
216 ScTabStops( ScCheckListMenuWindow
* mpMenuWin
);
218 void AddTabStop( vcl::Window
* pWin
);
219 void SetTabStop( vcl::Window
* pWin
);
220 void CycleFocus( bool bReverse
= false );
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
);
236 ScCheckListBox( vcl::Window
* pParent
);
237 virtual ~ScCheckListBox() override
{ disposeOnce(); }
238 virtual void dispose() override
{ mpCheckButton
.reset(); SvTreeListBox::dispose(); }
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
257 ScTabStops
* mpTabStops
;
259 ScSearchEdit(Window
* 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
279 OUString maName
; // node name
284 DatePartType meDatePartType
;
285 // To store Year and Month if the member if DAY type
286 std::vector
<OUString
> maDateParts
;
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
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
&&
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.
333 bool mbAllowEmptySet
;
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
);
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
);
375 virtual void handlePopupEnd() override
;
379 class CancelButton
: public ::CancelButton
382 CancelButton(ScCheckListMenuWindow
* pParent
);
383 virtual ~CancelButton() override
;
384 virtual void dispose() override
;
386 virtual void Click() override
;
389 VclPtr
<ScCheckListMenuWindow
> mpParent
;
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.
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.
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 );
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
;
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
;
440 Size maWndSize
; /// whole window size.
441 Size maMenuSize
; /// size of all menu items combined.
442 TriState mePrevToggleAllState
;
443 ScTabStops maTabStops
;
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */