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