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/scrbar.hxx>
17 #include <vcl/timer.hxx>
18 #include <svx/checklbx.hxx>
21 #include <unordered_map>
24 namespace com
{ namespace sun
{ namespace star
{
26 namespace accessibility
{
33 class ScAccessibleFilterMenu
;
35 class ScMenuFloatingWindow
: public PopupMenuFloatingWindow
38 static size_t MENU_NOT_SELECTED
;
40 * Action to perform when an event takes place. Create a sub-class of
41 * this to implement the desired 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
);
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
;}
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
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
;}
102 css::uno::Reference
<css::accessibility::XAccessible
> mxAccessible
;
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
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();
154 std::shared_ptr
<Action
> mpAction
;
155 VclPtr
<ScMenuFloatingWindow
> mpSubMenuWin
;
160 std::vector
<MenuItemData
> maMenuItems
;
162 struct SubMenuItemData
165 VclPtr
<ScMenuFloatingWindow
> mpSubMenu
;
168 DECL_LINK_TYPED( TimeoutHdl
, Timer
*, void );
170 SubMenuItemData(ScMenuFloatingWindow
* pParent
);
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.
186 size_t mnSelectedMenu
;
187 size_t mnClickedMenu
;
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());
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
;
214 ScTabStops( ScCheckListMenuWindow
* mpMenuWin
);
216 void AddTabStop( vcl::Window
* pWin
);
217 void SetTabStop( vcl::Window
* pWin
);
218 void CycleFocus( bool bReverse
= false );
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 );
234 ScCheckListBox( vcl::Window
* pParent
, WinBits nWinStyle
= 0 );
235 virtual ~ScCheckListBox() { disposeOnce(); }
236 virtual void dispose() override
{ delete mpCheckButton
; SvTreeListBox::dispose(); }
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
254 ScTabStops
* mpTabStops
;
256 ScSearchEdit(Window
* 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
277 OUString maName
; // node name
282 DatePartType meDatePartType
;
283 // To store Year and Month if the member if DAY type
284 std::vector
<OUString
> maDateParts
;
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
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.
313 bool mbAllowEmptySet
;
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
);
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
);
354 virtual void handlePopupEnd() override
;
358 class CancelButton
: public ::CancelButton
361 CancelButton(ScCheckListMenuWindow
* pParent
);
362 virtual ~CancelButton();
363 virtual void dispose() override
;
365 virtual void Click() override
;
368 VclPtr
<ScCheckListMenuWindow
> mpParent
;
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.
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.
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 );
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
;
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
;
419 Size maWndSize
; /// whole window size.
420 Size maMenuSize
; /// size of all menu items combined.
421 TriState mePrevToggleAllState
;
422 ScTabStops maTabStops
;
427 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */