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