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 INCLUDED_SC_SOURCE_UI_INC_CHECKLISTMENU_HXX
11 : #define INCLUDED_SC_SOURCE_UI_INC_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(vcl::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 0 : size_t getSelectedMenuItem() const { return mnSelectedMenu;}
69 :
70 : void setName(const OUString& rName);
71 0 : const OUString& getName() const { return maName;}
72 :
73 : void executeMenuItem(size_t nPos);
74 : void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const;
75 0 : ScMenuFloatingWindow* getParentMenuWindow() const { return mpParentMenu;}
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 0 : const vcl::Font& getLabelFont() const { return maLabelFont;}
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 0 : ScDocument* getDoc() { return mpDoc;}
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 : vcl::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 : class ScCheckListBox : public SvTreeListBox
190 : {
191 : SvLBoxButtonData* mpCheckButton;
192 : SvTreeListEntry* CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const;
193 : void CheckAllChildren( SvTreeListEntry* pEntry, bool bCheck = true );
194 :
195 : public:
196 :
197 : ScCheckListBox( vcl::Window* pParent, WinBits nWinStyle = 0 );
198 0 : virtual ~ScCheckListBox() { delete mpCheckButton; }
199 : void Init();
200 : void CheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bCheck = true );
201 : void CheckEntry( SvTreeListEntry* pEntry, bool bCheck = true );
202 : bool IsChecked( const OUString& sName, SvTreeListEntry* pParent );
203 : SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode );
204 : sal_uInt16 GetCheckedEntryCount() const;
205 : void ExpandChildren( SvTreeListEntry* pParent );
206 : virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
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<OUString, bool, 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 0 : virtual ~ExtendedData() {}
224 :
225 : };
226 :
227 : /**
228 : * Configuration options for this popup window.
229 : */
230 : struct Config
231 : {
232 : bool mbAllowEmptySet;
233 : bool mbRTL;
234 : Config();
235 : };
236 :
237 : explicit ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc);
238 : virtual ~ScCheckListMenuWindow();
239 :
240 : virtual void MouseMove(const MouseEvent& rMEvt) SAL_OVERRIDE;
241 : virtual bool Notify(NotifyEvent& rNEvt) SAL_OVERRIDE;
242 : virtual void Paint(const Rectangle& rRect) SAL_OVERRIDE;
243 : virtual vcl::Window* GetPreferredKeyInputWindow() SAL_OVERRIDE;
244 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE;
245 :
246 : void setMemberSize(size_t n);
247 : void addDateMember(const OUString& rName, double nVal, bool bVisible);
248 : void addMember(const OUString& rName, bool bVisible);
249 : void initMembers();
250 : void setConfig(const Config& rConfig);
251 :
252 : bool isAllSelected() const;
253 : void getResult(ResultType& rResult);
254 : void launch(const Rectangle& rRect);
255 : void close(bool bOK);
256 :
257 : /**
258 : * Set auxiliary data that the client code might need. Note that this
259 : * popup window class manages its life time; no explicit deletion of the
260 : * instance is needed in the client code.
261 : */
262 : void setExtendedData(ExtendedData* p);
263 :
264 : /**
265 : * Get the store auxiliary data, or NULL if no such data is stored.
266 : */
267 : ExtendedData* getExtendedData();
268 :
269 : void setOKAction(Action* p);
270 : void setPopupEndAction(Action* p);
271 :
272 : protected:
273 : virtual void handlePopupEnd() SAL_OVERRIDE;
274 :
275 : private:
276 0 : struct Member
277 : {
278 : OUString maName; // node name
279 : OUString maRealName;
280 : bool mbVisible;
281 : bool mbDate;
282 : bool mbLeaf;
283 :
284 : Member();
285 : SvTreeListEntry* mpParent;
286 : };
287 :
288 0 : class CancelButton : public ::CancelButton
289 : {
290 : public:
291 : CancelButton(ScCheckListMenuWindow* pParent);
292 :
293 : virtual void Click() SAL_OVERRIDE;
294 :
295 : private:
296 : ScCheckListMenuWindow* mpParent;
297 : };
298 :
299 : enum SectionType {
300 : WHOLE, // entire window
301 : LISTBOX_AREA_OUTER, // box enclosing the check box items.
302 : LISTBOX_AREA_INNER, // box enclosing the check box items.
303 : SINGLE_BTN_AREA, // box enclosing the single-action buttons.
304 : CHECK_TOGGLE_ALL, // check box for toggling all items.
305 : BTN_SINGLE_SELECT,
306 : BTN_SINGLE_UNSELECT,
307 : BTN_OK, // OK button
308 : BTN_CANCEL, // Cancel button
309 : };
310 : void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const;
311 :
312 : /**
313 : * Calculate the appropriate window size, the position and size of each
314 : * control based on the menu items.
315 : */
316 : void packWindow();
317 : void setAllMemberState(bool bSet);
318 : void selectCurrentMemberOnly(bool bSet);
319 : void cycleFocus(bool bReverse = false);
320 :
321 : DECL_LINK( ButtonHdl, Button* );
322 : DECL_LINK( TriStateHdl, void* );
323 : DECL_LINK( CheckHdl, SvTreeListBox* );
324 :
325 : private:
326 : SvTreeListEntry* findEntry( SvTreeListEntry* pParent, const OUString& rText );
327 :
328 : ScCheckListBox maChecks;
329 :
330 : TriStateBox maChkToggleAll;
331 : ImageButton maBtnSelectSingle;
332 : ImageButton maBtnUnselectSingle;
333 :
334 : OKButton maBtnOk;
335 : CancelButton maBtnCancel;
336 :
337 : ::std::vector<vcl::Window*> maTabStopCtrls;
338 : size_t mnCurTabStop;
339 :
340 : ::std::vector<Member> maMembers;
341 : boost::scoped_ptr<ExtendedData> mpExtendedData;
342 : boost::scoped_ptr<Action> mpOKAction;
343 : boost::scoped_ptr<Action> mpPopupEndAction;
344 :
345 : Config maConfig;
346 : Size maWndSize; /// whole window size.
347 : Size maMenuSize; /// size of all menu items combined.
348 : TriState mePrevToggleAllState;
349 : };
350 :
351 : #endif
352 :
353 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|