Line data Source code
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 __SC_CHECKLISTMENU_HXX__
11 : #define __SC_CHECKLISTMENU_HXX__
12 :
13 : #include "vcl/popupmenuwindow.hxx"
14 : #include "vcl/button.hxx"
15 : #include "vcl/scrbar.hxx"
16 : #include "vcl/timer.hxx"
17 : #include "svx/checklbx.hxx"
18 :
19 : #include <boost/unordered_map.hpp>
20 : #include <boost/scoped_ptr.hpp>
21 :
22 : namespace com { namespace sun { namespace star {
23 :
24 : namespace accessibility {
25 : class XAccessible;
26 : }
27 :
28 : }}}
29 :
30 : class ScDocument;
31 : class ScAccessibleFilterMenu;
32 :
33 : class ScMenuFloatingWindow : public PopupMenuFloatingWindow
34 : {
35 : public:
36 : static size_t MENU_NOT_SELECTED;
37 : /**
38 : * Action to perform when an event takes place. Create a sub-class of
39 : * this to implement the desired action.
40 : */
41 0 : class Action
42 : {
43 : public:
44 0 : virtual ~Action() {}
45 : virtual void execute() = 0;
46 : };
47 :
48 : explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, sal_uInt16 nMenuStackLevel = 0);
49 : virtual ~ScMenuFloatingWindow();
50 :
51 : virtual void PopupModeEnd() SAL_OVERRIDE;
52 : virtual void MouseMove(const MouseEvent& rMEvt) SAL_OVERRIDE;
53 : virtual void MouseButtonDown(const MouseEvent& rMEvt) SAL_OVERRIDE;
54 : virtual void MouseButtonUp(const MouseEvent& rMEvt) SAL_OVERRIDE;
55 : virtual void KeyInput(const KeyEvent& rKEvt) SAL_OVERRIDE;
56 : virtual void Paint(const Rectangle& rRect) SAL_OVERRIDE;
57 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE;
58 :
59 : void addMenuItem(const OUString& rText, bool bEnabled, Action* pAction);
60 : void addSeparator();
61 :
62 : ScMenuFloatingWindow* addSubMenuItem(const OUString& rText, bool bEnabled);
63 : void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu);
64 : void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer);
65 : void clearSelectedMenuItem();
66 : ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const;
67 : bool isMenuItemSelected(size_t nPos) const;
68 : size_t getSelectedMenuItem() const;
69 :
70 : void setName(const OUString& rName);
71 : const OUString& getName() const;
72 :
73 : void executeMenuItem(size_t nPos);
74 : void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const;
75 : ScMenuFloatingWindow* getParentMenuWindow() const;
76 :
77 : protected:
78 : virtual void handlePopupEnd();
79 :
80 : Size getMenuSize() const;
81 : void drawMenuItem(size_t nPos);
82 : void drawSeparator(size_t nPos);
83 : void drawAllMenuItems();
84 : const Font& getLabelFont() const;
85 :
86 : void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu);
87 : void queueCloseSubMenu();
88 : void launchSubMenu(bool bSetMenuPos);
89 : void endSubMenu(ScMenuFloatingWindow* pSubMenu);
90 :
91 : void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const;
92 :
93 : ScDocument* getDoc();
94 :
95 : protected:
96 : ::com::sun::star::uno::Reference<
97 : ::com::sun::star::accessibility::XAccessible > mxAccessible;
98 :
99 : private:
100 : struct SubMenuItemData;
101 : void handleMenuTimeout(SubMenuItemData* pTimer);
102 :
103 : void resizeToFitMenuItems();
104 : void highlightMenuItem(size_t nPos, bool bSelected);
105 :
106 : size_t getEnclosingMenuItem(const Point& rPos) const;
107 : size_t getSubMenuPos(ScMenuFloatingWindow* pSubMenu);
108 :
109 : /**
110 : * Fire a menu highlight event since the accessibility framework needs
111 : * this to track focus on menu items.
112 : */
113 : void fireMenuHighlightedEvent();
114 :
115 : /**
116 : * Make sure that the specified submenu is permanently up, the submenu
117 : * close timer is not active, and the correct menu item associated with
118 : * the submenu is highlighted.
119 : */
120 : void setSubMenuFocused(ScMenuFloatingWindow* pSubMenu);
121 :
122 : /**
123 : * When a menu item of an invisible submenu is selected, we need to make
124 : * sure that all its parent menu(s) are visible, with the right menu item
125 : * highlighted in each of the parents. Calling this method ensures it.
126 : */
127 : void ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu);
128 :
129 : /**
130 : * Dismiss any visible child submenus when a menu item of a parent menu is
131 : * selected.
132 : */
133 : void ensureSubMenuNotVisible();
134 :
135 : /**
136 : * Dismiss all visible popup menus and set focus back to the application
137 : * window. This method is called e.g. when a menu action is fired.
138 : */
139 : void terminateAllPopupMenus();
140 :
141 : private:
142 :
143 0 : struct MenuItemData
144 : {
145 : OUString maText;
146 : bool mbEnabled:1;
147 : bool mbSeparator:1;
148 :
149 : ::boost::shared_ptr<Action> mpAction;
150 : ::boost::shared_ptr<ScMenuFloatingWindow> mpSubMenuWin;
151 :
152 : MenuItemData();
153 : };
154 :
155 : ::std::vector<MenuItemData> maMenuItems;
156 :
157 0 : struct SubMenuItemData
158 : {
159 : Timer maTimer;
160 : ScMenuFloatingWindow* mpSubMenu;
161 : size_t mnMenuPos;
162 :
163 : DECL_LINK( TimeoutHdl, void* );
164 :
165 : SubMenuItemData(ScMenuFloatingWindow* pParent);
166 : void reset();
167 :
168 : private:
169 : ScMenuFloatingWindow* mpParent;
170 : };
171 : SubMenuItemData maOpenTimer;
172 : SubMenuItemData maCloseTimer;
173 :
174 : Font maLabelFont;
175 :
176 : // Name of this menu window, taken from the menu item of the parent window
177 : // that launches it (if this is a sub menu). If this is a top-level menu
178 : // window, then this name can be anything.
179 : OUString maName;
180 :
181 : size_t mnSelectedMenu;
182 : size_t mnClickedMenu;
183 :
184 : ScDocument* mpDoc;
185 :
186 : ScMenuFloatingWindow* mpParentMenu;
187 : };
188 :
189 :
190 : class ScCheckListBox : public SvTreeListBox
191 : {
192 : SvLBoxButtonData* mpCheckButton;
193 : SvTreeListEntry* CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const;
194 : void CheckAllChildren( SvTreeListEntry* pEntry, bool bCheck = true );
195 :
196 : public:
197 :
198 : ScCheckListBox( Window* pParent, WinBits nWinStyle = 0 );
199 0 : virtual ~ScCheckListBox() { delete mpCheckButton; }
200 : void Init();
201 : void CheckEntry( OUString& sName, SvTreeListEntry* pParent, bool bCheck = true );
202 : void CheckEntry( SvTreeListEntry* pEntry, bool bCheck = true );
203 : bool IsChecked( OUString& sName, SvTreeListEntry* pParent );
204 : SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode );
205 : sal_uInt16 GetCheckedEntryCount() const;
206 : void ExpandChildren( SvTreeListEntry* pParent );
207 : virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
208 : };
209 : /**
210 : * This class implements a popup window for field button, for quick access
211 : * of hide-item list, and possibly more stuff related to field options.
212 : */
213 : class ScCheckListMenuWindow : public ScMenuFloatingWindow
214 : {
215 : public:
216 : typedef boost::unordered_map<OUString, bool, OUStringHash> ResultType;
217 :
218 : /**
219 : * Extended data that the client code may need to store. Create a
220 : * sub-class of this and store data there.
221 : */
222 0 : struct ExtendedData {
223 :
224 0 : virtual ~ExtendedData() {}
225 :
226 : };
227 :
228 : /**
229 : * Configuration options for this popup window.
230 : */
231 : struct Config
232 : {
233 : bool mbAllowEmptySet;
234 : bool mbRTL;
235 : Config();
236 : };
237 :
238 : explicit ScCheckListMenuWindow(Window* pParent, ScDocument* pDoc);
239 : virtual ~ScCheckListMenuWindow();
240 :
241 : virtual void MouseMove(const MouseEvent& rMEvt) SAL_OVERRIDE;
242 : virtual bool Notify(NotifyEvent& rNEvt) SAL_OVERRIDE;
243 : virtual void Paint(const Rectangle& rRect) SAL_OVERRIDE;
244 : virtual Window* GetPreferredKeyInputWindow() SAL_OVERRIDE;
245 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE;
246 :
247 : void setMemberSize(size_t n);
248 : void addDateMember(const OUString& rName, double nVal, bool bVisible);
249 : void addMember(const OUString& rName, bool bVisible);
250 : void initMembers();
251 : void setConfig(const Config& rConfig);
252 :
253 : bool isAllSelected() const;
254 : void getResult(ResultType& rResult);
255 : void launch(const Rectangle& rRect);
256 : void close(bool bOK);
257 :
258 : /**
259 : * Set auxiliary data that the client code might need. Note that this
260 : * popup window class manages its life time; no explicit deletion of the
261 : * instance is needed in the client code.
262 : */
263 : void setExtendedData(ExtendedData* p);
264 :
265 : /**
266 : * Get the store auxiliary data, or NULL if no such data is stored.
267 : */
268 : ExtendedData* getExtendedData();
269 :
270 : void setOKAction(Action* p);
271 : void setPopupEndAction(Action* p);
272 :
273 : protected:
274 : virtual void handlePopupEnd() SAL_OVERRIDE;
275 :
276 : private:
277 0 : struct Member
278 : {
279 : OUString maName; // node name
280 : OUString maRealName;
281 : bool mbVisible;
282 : bool mbDate;
283 : bool mbLeaf;
284 :
285 : Member();
286 : SvTreeListEntry* mpParent;
287 : };
288 :
289 0 : class CancelButton : public ::CancelButton
290 : {
291 : public:
292 : CancelButton(ScCheckListMenuWindow* pParent);
293 :
294 : virtual void Click() SAL_OVERRIDE;
295 :
296 : private:
297 : ScCheckListMenuWindow* mpParent;
298 : };
299 :
300 : enum SectionType {
301 : WHOLE, // entire window
302 : LISTBOX_AREA_OUTER, // box enclosing the check box items.
303 : LISTBOX_AREA_INNER, // box enclosing the check box items.
304 : SINGLE_BTN_AREA, // box enclosing the single-action buttons.
305 : CHECK_TOGGLE_ALL, // check box for toggling all items.
306 : BTN_SINGLE_SELECT,
307 : BTN_SINGLE_UNSELECT,
308 : BTN_OK, // OK button
309 : BTN_CANCEL, // Cancel button
310 : };
311 : void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const;
312 :
313 : /**
314 : * Calculate the appropriate window size, the position and size of each
315 : * control based on the menu items.
316 : */
317 : void packWindow();
318 : void setAllMemberState(bool bSet);
319 : void selectCurrentMemberOnly(bool bSet);
320 : void cycleFocus(bool bReverse = false);
321 :
322 : DECL_LINK( ButtonHdl, Button* );
323 : DECL_LINK( TriStateHdl, void* );
324 : DECL_LINK( CheckHdl, SvTreeListBox* );
325 :
326 : private:
327 : SvTreeListEntry* findEntry( SvTreeListEntry* pParent, const OUString& rText );
328 :
329 : ScCheckListBox maChecks;
330 :
331 : TriStateBox maChkToggleAll;
332 : ImageButton maBtnSelectSingle;
333 : ImageButton maBtnUnselectSingle;
334 :
335 : OKButton maBtnOk;
336 : CancelButton maBtnCancel;
337 :
338 : ::std::vector<Window*> maTabStopCtrls;
339 : size_t mnCurTabStop;
340 :
341 : ::std::vector<Member> maMembers;
342 : boost::scoped_ptr<ExtendedData> mpExtendedData;
343 : boost::scoped_ptr<Action> mpOKAction;
344 : boost::scoped_ptr<Action> mpPopupEndAction;
345 :
346 : Config maConfig;
347 : Size maWndSize; /// whole window size.
348 : Size maMenuSize; /// size of all menu items combined.
349 : TriState mePrevToggleAllState;
350 : };
351 :
352 : #endif
353 :
354 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|