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