Overte C++ Documentation
libraries/ui/src/ui/Menu.h
1 //
2 // Created by Stephen Birarda on 8/12/13.
3 // Copyright 2013 High Fidelity, Inc.
4 //
5 // Distributed under the Apache License, Version 2.0.
6 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
7 //
8 
9 #ifndef hifi_ui_Menu_h
10 #define hifi_ui_Menu_h
11 
12 #include <functional>
13 
14 #include <QtCore/QDir>
15 #include <QtCore/QPointer>
16 #include <QtCore/QStandardPaths>
17 #include <QtCore/QHash>
18 #include <QtGui/QKeySequence>
19 #include <QtWidgets/QMenuBar>
20 
21 class Settings;
22 namespace ui {
23  class Menu;
24 }
25 
26 class MenuWrapper : public QObject {
27 public:
28 
29  QList<QAction*> actions();
30  MenuWrapper* addMenu(const QString& menuName);
31  void setEnabled(bool enabled = true);
32 
33  bool isVisible();
34  void setVisible(bool visible = true);
35  QAction* addSeparator();
36  void addAction(QAction* action);
37 
38  QAction* addAction(const QString& menuName);
39  void insertAction(QAction* before, QAction* menuName);
40 
41  QAction* addAction(const QString& menuName, const QObject* receiver, const char* member, const QKeySequence& shortcut = 0);
42  void removeAction(QAction* action);
43 
44  QAction* newAction() {
45  return new QAction(_realMenu);
46  }
47 
48 private:
49  MenuWrapper(ui::Menu& rootMenu, QMenu* menu);
50  ui::Menu& _rootMenu;
51  QMenu* const _realMenu;
52  friend class ui::Menu;
53 };
54 
55 namespace ui {
56 
57 class Menu : public QMenuBar {
58  Q_OBJECT
59 public:
60  static const int UNSPECIFIED_POSITION = -1;
61 
62  Menu();
63 
64  void loadSettings();
65  void saveSettings();
66 
67  MenuWrapper* getMenu(const QString& menuName);
68  MenuWrapper* getSubMenuFromName(const QString& menuName, MenuWrapper* menu);
69 
70  QAction* getActionForOption(const QString& menuOption);
71 
72  QAction* addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
73  const QString& actionName,
74  const QKeySequence& shortcut = 0,
75  const QObject* receiver = NULL,
76  const char* member = NULL,
77  QAction::MenuRole role = QAction::NoRole,
78  int menuItemLocation = UNSPECIFIED_POSITION,
79  const QString& grouping = QString());
80 
81  QAction* addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
82  QAction* action,
83  const QString& actionName = QString(),
84  const QKeySequence& shortcut = 0,
85  QAction::MenuRole role = QAction::NoRole,
86  int menuItemLocation = UNSPECIFIED_POSITION,
87  const QString& grouping = QString());
88 
89  QAction* addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
90  const QString& actionName,
91  const QKeySequence& shortcut = 0,
92  const bool checked = false,
93  const QObject* receiver = NULL,
94  const char* member = NULL,
95  int menuItemLocation = UNSPECIFIED_POSITION,
96  const QString& grouping = QString());
97 
98  QAction* addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
99  const QString& actionName,
100  const std::function<void(bool)>& handler,
101  const QKeySequence& shortcut = 0,
102  const bool checked = false,
103  int menuItemLocation = UNSPECIFIED_POSITION,
104  const QString& grouping = QString());
105 
106  void removeAction(MenuWrapper* menu, const QString& actionName);
107 
108 public slots:
109  MenuWrapper* addMenu(const QString& menuName, const QString& grouping = QString());
110  void removeMenu(const QString& menuName);
111  bool menuExists(const QString& menuName);
112  void addSeparator(const QString& menuName, const QString& separatorName, const QString& grouping = QString());
113  void removeSeparator(const QString& menuName, const QString& separatorName);
114  void removeMenuItem(const QString& menuName, const QString& menuitem);
115  bool menuItemExists(const QString& menuName, const QString& menuitem);
116  bool isOptionChecked(const QString& menuOption) const;
117  void setIsOptionChecked(const QString& menuOption, bool isChecked);
118 
119  bool isMenuEnabled(const QString& menuName);
120  void setMenuEnabled(const QString& menuName, bool isEnabled);
121 
122  bool getGroupingIsVisible(const QString& grouping);
123  void setGroupingIsVisible(const QString& grouping, bool isVisible);
124 
125  void toggleDeveloperMenus();
126  void toggleAdvancedMenus();
127 
128  void triggerOption(const QString& menuOption);
129 
130  static bool isSomeSubmenuShown() { return _isSomeSubmenuShown; }
131 
132 protected:
133  typedef void(*settingsAction)(Settings&, QAction&);
134  static void loadAction(Settings& settings, QAction& action);
135  static void saveAction(Settings& settings, QAction& action);
136  void scanMenuBar(settingsAction modifySetting);
137  void scanMenu(QMenu& menu, settingsAction modifySetting, Settings& settings);
138 
140  void addDisabledActionAndSeparator(MenuWrapper* destinationMenu,
141  const QString& actionName,
142  int menuItemLocation = UNSPECIFIED_POSITION,
143  const QString& grouping = QString());
144 
145  QAction* getActionFromName(const QString& menuName, MenuWrapper* menu);
146  MenuWrapper* getMenuParent(const QString& menuName, QString& finalMenuPart);
147 
148  QAction* getMenuAction(const QString& menuName);
149  int findPositionOfMenuItem(MenuWrapper* menu, const QString& searchMenuItem);
150  int positionBeforeSeparatorIfNeeded(MenuWrapper* menu, int requestedPosition);
151 
152  // There is a design flaw here -- _actionHash is system-wide and hashes the names of menu-items to their
153  // QActions. The path (parent submenu name etc) isn't included in the hash key. This generally works,
154  // but we add "Home" twice -- once for "go home" and once for "set startup location to home". Anytime
155  // a user bookmarks a place and gives it a name like an existing menu-item, something will go wrong.
156  // TODO: change the js api to require the full path when referring to a specific menu item.
157  QHash<QString, QAction*> _actionHash;
158 
159  bool isValidGrouping(const QString& grouping) const { return grouping == "Advanced" || grouping == "Developer"; }
160  QHash<QString, bool> _groupingVisible;
161  QHash<QString, QSet<QAction*>> _groupingActions;
162  QHash<QMenu*, MenuWrapper*> _backMap;
163 
164  static bool _isSomeSubmenuShown;
165  friend class ::MenuWrapper;
166 };
167 
168 } // namespace ui
169 
170 #endif // hifi_Menu_h
QSettings analog.
Definition: SettingHandle.h:56