xref: /trunk/main/sc/source/ui/inc/dpcontrol.hxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef SC_DPCONTROL_HXX
29 #define SC_DPCONTROL_HXX
30 
31 #include "rtl/ustring.hxx"
32 #include "tools/gen.hxx"
33 #include "tools/fract.hxx"
34 #include "vcl/popupmenuwindow.hxx"
35 #include "vcl/button.hxx"
36 #include "vcl/scrbar.hxx"
37 #include "vcl/timer.hxx"
38 #include "svx/checklbx.hxx"
39 
40 #include <boost/shared_ptr.hpp>
41 #include <memory>
42 #include <hash_map>
43 
44 namespace com { namespace sun { namespace star {
45 
46     namespace accessibility {
47         class XAccessible;
48     }
49 
50 }}}
51 
52 class OutputDevice;
53 class Point;
54 class Size;
55 class StyleSettings;
56 class Window;
57 class ScDocument;
58 class ScAccessibleFilterMenu;
59 
60 /**
61  * This class takes care of physically drawing field button controls inside
62  * data pilot tables.
63  */
64 class ScDPFieldButton
65 {
66 public:
67     ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX = NULL, const Fraction* pZoomY = NULL,
68                     ScDocument* pDoc = NULL);
69     ~ScDPFieldButton();
70 
71     void setText(const ::rtl::OUString& rText);
72     void setBoundingBox(const Point& rPos, const Size& rSize, bool bLayoutRTL);
73     void setDrawBaseButton(bool b);
74     void setDrawPopupButton(bool b);
75     void setHasHiddenMember(bool b);
76     void setPopupPressed(bool b);
77     void setPopupLeft(bool b);
78     void draw();
79 
80     void getPopupBoundingBox(Point& rPos, Size& rSize) const;
81 
82 private:
83     void drawPopupButton();
84 
85 private:
86     Point                   maPos;
87     Size                    maSize;
88     ::rtl::OUString         maText;
89     Fraction                maZoomX;
90     Fraction                maZoomY;
91     ScDocument*             mpDoc;
92     OutputDevice*           mpOutDev;
93     const StyleSettings*    mpStyle;
94     bool                    mbBaseButton;
95     bool                    mbPopupButton;
96     bool                    mbHasHiddenMember;
97     bool                    mbPopupPressed;
98     bool                    mbPopupLeft;
99 };
100 
101 // ============================================================================
102 
103 class ScMenuFloatingWindow : public PopupMenuFloatingWindow
104 {
105 public:
106     static size_t MENU_NOT_SELECTED;
107     /**
108      * Action to perform when an event takes place.  Create a sub-class of
109      * this to implement the desired action.
110      */
111     class Action
112     {
113     public:
114         virtual void execute() = 0;
115     };
116 
117     explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, sal_uInt16 nMenuStackLevel = 0);
118     virtual ~ScMenuFloatingWindow();
119 
120     virtual void MouseMove(const MouseEvent& rMEvt);
121     virtual void MouseButtonDown(const MouseEvent& rMEvt);
122     virtual void MouseButtonUp(const MouseEvent& rMEvt);
123     virtual void KeyInput(const KeyEvent& rKEvt);
124     virtual void Paint(const Rectangle& rRect);
125     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
126 
127     void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction);
128     ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled);
129     void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu);
130     void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer);
131     void clearSelectedMenuItem();
132     ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const;
133     bool isMenuItemSelected(size_t nPos) const;
134     size_t getSelectedMenuItem() const;
135 
136     void setName(const ::rtl::OUString& rName);
137     const ::rtl::OUString& getName() const;
138 
139     void executeMenuItem(size_t nPos);
140     void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const;
141     ScMenuFloatingWindow* getParentMenuWindow() const;
142 
143 protected:
144 
145     void drawMenuItem(size_t nPos);
146     void drawAllMenuItems();
147     const Font& getLabelFont() const;
148 
149     void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu);
150     void queueCloseSubMenu();
151     void launchSubMenu(bool bSetMenuPos);
152     void endSubMenu(ScMenuFloatingWindow* pSubMenu);
153 
154     void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const;
155 
156     ScDocument* getDoc();
157 
158 protected:
159     ::com::sun::star::uno::Reference<
160         ::com::sun::star::accessibility::XAccessible > mxAccessible;
161 
162 private:
163     struct SubMenuItemData;
164     void handleMenuTimeout(SubMenuItemData* pTimer);
165 
166     void resizeToFitMenuItems();
167     void highlightMenuItem(size_t nPos, bool bSelected);
168 
169     size_t getEnclosingMenuItem(const Point& rPos) const;
170     size_t getSubMenuPos(ScMenuFloatingWindow* pSubMenu);
171 
172     /**
173      * Fire a menu highlight event since the accessibility framework needs
174      * this to track focus on menu items.
175      */
176     void fireMenuHighlightedEvent();
177 
178     /**
179      * Make sure that the specified submenu is permanently up, the submenu
180      * close timer is not active, and the correct menu item associated with
181      * the submenu is highlighted.
182      */
183     void setSubMenuFocused(ScMenuFloatingWindow* pSubMenu);
184 
185     /**
186      * When a menu item of an invisible submenu is selected, we need to make
187      * sure that all its parent menu(s) are visible, with the right menu item
188      * highlighted in each of the parents.  Calling this method ensures it.
189      */
190     void ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu);
191 
192     /**
193      * Dismiss any visible child submenus when a menu item of a parent menu is
194      * selected.
195      */
196     void ensureSubMenuNotVisible();
197 
198     /**
199      * Dismiss all visible popup menus and set focus back to the application
200      * window.  This method is called e.g. when a menu action is fired.
201      */
202     void terminateAllPopupMenus();
203 
204     DECL_LINK( PopupEndHdl, void* );
205 
206 private:
207 
208     struct MenuItemData
209     {
210         ::rtl::OUString maText;
211         bool            mbEnabled;
212 
213         ::boost::shared_ptr<Action> mpAction;
214         ::boost::shared_ptr<ScMenuFloatingWindow> mpSubMenuWin;
215 
216         MenuItemData();
217     };
218 
219     ::std::vector<MenuItemData>         maMenuItems;
220 
221     struct SubMenuItemData
222     {
223         Timer                   maTimer;
224         ScMenuFloatingWindow*   mpSubMenu;
225         size_t                  mnMenuPos;
226 
227         DECL_LINK( TimeoutHdl, void* );
228 
229         SubMenuItemData(ScMenuFloatingWindow* pParent);
230         void reset();
231 
232     private:
233         ScMenuFloatingWindow* mpParent;
234     };
235     SubMenuItemData   maOpenTimer;
236     SubMenuItemData   maCloseTimer;
237 
238     Font    maLabelFont;
239 
240     // Name of this menu window, taken from the menu item of the parent window
241     // that launches it (if this is a sub menu).  If this is a top-level menu
242     // window, then this name can be anything.
243     ::rtl::OUString maName;
244 
245     size_t  mnSelectedMenu;
246     size_t  mnClickedMenu;
247 
248     ScDocument* mpDoc;
249 
250     ScMenuFloatingWindow* mpParentMenu;
251     ScMenuFloatingWindow* mpActiveSubMenu;
252 };
253 
254 // ============================================================================
255 
256 /**
257  * This class implements a popup window for field button, for quick access
258  * of hide-item list, and possibly more stuff related to field options.
259  */
260 class ScDPFieldPopupWindow : public ScMenuFloatingWindow
261 {
262 public:
263     /**
264      * Extended data that the client code may need to store.  Create a
265      * sub-class of this and store data there.
266      */
267     struct ExtendedData {};
268 
269     explicit ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc);
270     virtual ~ScDPFieldPopupWindow();
271 
272     virtual void MouseMove(const MouseEvent& rMEvt);
273     virtual long Notify(NotifyEvent& rNEvt);
274     virtual void Paint(const Rectangle& rRect);
275     virtual Window* GetPreferredKeyInputWindow();
276     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
277 
278     void setMemberSize(size_t n);
279     void addMember(const ::rtl::OUString& rName, bool bVisible);
280     void initMembers();
281 
282     const Size& getWindowSize() const;
283 
284     void getResult(::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rResult);
285     void close(bool bOK);
286 
287     /**
288      * Set auxiliary data that the client code might need.  Note that this
289      * popup window class manages its life time; no explicit deletion of the
290      * instance is needed in the client code.
291      */
292     void setExtendedData(ExtendedData* p);
293 
294     /**
295      * Get the store auxiliary data, or NULL if no such data is stored.
296      */
297     ExtendedData* getExtendedData();
298 
299     void setOKAction(Action* p);
300 
301 private:
302     struct Member
303     {
304         ::rtl::OUString maName;
305         bool            mbVisible;
306 
307         Member();
308     };
309 
310     class CancelButton : public ::CancelButton
311     {
312     public:
313         CancelButton(ScDPFieldPopupWindow* pParent);
314 
315         virtual void Click();
316 
317     private:
318         ScDPFieldPopupWindow* mpParent;
319     };
320 
321     enum SectionType {
322         WHOLE,                // entire window
323         LISTBOX_AREA_OUTER,   // box enclosing the check box items.
324         LISTBOX_AREA_INNER,   // box enclosing the check box items.
325         SINGLE_BTN_AREA,      // box enclosing the single-action buttons.
326         CHECK_TOGGLE_ALL,     // check box for toggling all items.
327         BTN_SINGLE_SELECT,
328         BTN_SINGLE_UNSELECT,
329         BTN_OK,               // OK button
330         BTN_CANCEL,           // Cancel button
331     };
332     void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const;
333 
334     void setAllMemberState(bool bSet);
335     void selectCurrentMemberOnly(bool bSet);
336     void cycleFocus(bool bReverse = false);
337 
338     DECL_LINK( ButtonHdl, Button* );
339     DECL_LINK( TriStateHdl, TriStateBox* );
340     DECL_LINK( CheckHdl, SvTreeListBox* );
341 
342 private:
343     SvxCheckListBox maChecks;
344 
345     TriStateBox     maChkToggleAll;
346     ImageButton     maBtnSelectSingle;
347     ImageButton     maBtnUnselectSingle;
348 
349     OKButton        maBtnOk;
350     CancelButton    maBtnCancel;
351 
352     ::std::vector<Window*>          maTabStopCtrls;
353     size_t                          mnCurTabStop;
354 
355     ::std::vector<Member>           maMembers;
356     ::std::auto_ptr<ExtendedData>   mpExtendedData;
357     ::std::auto_ptr<Action>         mpOKAction;
358 
359     const Size      maWndSize;  /// hard-coded window size.
360     TriState mePrevToggleAllState;
361 };
362 
363 #endif
364