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