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