1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtGui module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #ifndef QMENU_P_H |
43 | #define QMENU_P_H |
44 | |
45 | // |
46 | // W A R N I N G |
47 | // ------------- |
48 | // |
49 | // This file is not part of the Qt API. It exists purely as an |
50 | // implementation detail. This header file may change from version to |
51 | // version without notice, or even be removed. |
52 | // |
53 | // We mean it. |
54 | // |
55 | |
56 | #include "QtGui/qmenubar.h" |
57 | #include "QtGui/qstyleoption.h" |
58 | #include "QtCore/qdatetime.h" |
59 | #include "QtCore/qmap.h" |
60 | #include "QtCore/qhash.h" |
61 | #include "QtCore/qbasictimer.h" |
62 | #include "private/qwidget_p.h" |
63 | |
64 | #ifdef Q_WS_S60 |
65 | class CEikMenuPane; |
66 | #define QT_SYMBIAN_FIRST_MENU_ITEM 32000 |
67 | #define QT_SYMBIAN_LAST_MENU_ITEM 41999 // 10000 items ought to be enough for anybody... |
68 | #endif |
69 | QT_BEGIN_NAMESPACE |
70 | |
71 | #ifndef QT_NO_MENU |
72 | |
73 | #ifdef Q_WS_S60 |
74 | void qt_symbian_next_menu_from_action(QWidget* actionContainer); |
75 | void qt_symbian_show_toplevel(CEikMenuPane* menuPane); |
76 | void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id); |
77 | #endif // Q_WS_S60 |
78 | |
79 | class ; |
80 | class QEventLoop; |
81 | |
82 | #ifdef Q_WS_MAC |
83 | # ifdef __OBJC__ |
84 | QT_END_NAMESPACE |
85 | @class NSMenuItem; |
86 | QT_BEGIN_NAMESPACE |
87 | # else |
88 | typedef void NSMenuItem; |
89 | # endif //__OBJC__ |
90 | struct QMacMenuAction { |
91 | QMacMenuAction() |
92 | #ifndef QT_MAC_USE_COCOA |
93 | : command(0) |
94 | #else |
95 | : menuItem(0) |
96 | #endif |
97 | , ignore_accel(0), merged(0), menu(0) |
98 | { |
99 | } |
100 | ~QMacMenuAction(); |
101 | #ifndef QT_MAC_USE_COCOA |
102 | uint command; |
103 | #else |
104 | NSMenuItem *menuItem; |
105 | #endif |
106 | uchar ignore_accel : 1; |
107 | uchar merged : 1; |
108 | QPointer<QAction> action; |
109 | OSMenuRef menu; |
110 | }; |
111 | |
112 | struct QMenuMergeItem |
113 | { |
114 | #ifndef QT_MAC_USE_COCOA |
115 | inline QMenuMergeItem(MenuCommand c, QMacMenuAction *a) : command(c), action(a) { } |
116 | MenuCommand command; |
117 | #else |
118 | inline QMenuMergeItem(NSMenuItem *c, QMacMenuAction *a) : menuItem(c), action(a) { } |
119 | NSMenuItem *menuItem; |
120 | #endif |
121 | QMacMenuAction *action; |
122 | }; |
123 | typedef QList<QMenuMergeItem> QMenuMergeList; |
124 | #endif |
125 | |
126 | #ifdef Q_WS_WINCE |
127 | struct QWceMenuAction { |
128 | uint command; |
129 | QPointer<QAction> action; |
130 | HMENU menuHandle; |
131 | QWceMenuAction() : menuHandle(0), command(0) {} |
132 | }; |
133 | #endif |
134 | #ifdef Q_WS_S60 |
135 | struct QSymbianMenuAction { |
136 | uint command; |
137 | int parent; |
138 | CEikMenuPane* menuPane; |
139 | QPointer<QAction> action; |
140 | QSymbianMenuAction() : command(0) {} |
141 | }; |
142 | #endif |
143 | |
144 | class : public QWidgetPrivate |
145 | { |
146 | Q_DECLARE_PUBLIC(QMenu) |
147 | public: |
148 | () : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0), |
149 | collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0), |
150 | currentAction(0), |
151 | #ifdef QT_KEYPAD_NAVIGATION |
152 | selectAction(0), |
153 | cancelAction(0), |
154 | #endif |
155 | scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0), |
156 | hasCheckableItems(0), sloppyDelayTimer(0), sloppyAction(0), doChildEffects(false) |
157 | #ifdef QT3_SUPPORT |
158 | ,emitHighlighted(false) |
159 | #endif |
160 | #ifdef Q_WS_MAC |
161 | ,mac_menu(0) |
162 | #endif |
163 | #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) |
164 | ,wce_menu(0) |
165 | #endif |
166 | #ifdef Q_WS_S60 |
167 | ,symbian_menu(0) |
168 | #endif |
169 | { } |
170 | () |
171 | { |
172 | delete scroll; |
173 | #ifdef Q_WS_MAC |
174 | delete mac_menu; |
175 | #endif |
176 | #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) |
177 | delete wce_menu; |
178 | #endif |
179 | #ifdef Q_WS_S60 |
180 | delete symbian_menu; |
181 | #endif |
182 | |
183 | } |
184 | void (); |
185 | |
186 | static QMenuPrivate *(QMenu *m) { return m->d_func(); } |
187 | int () const; |
188 | |
189 | //item calculations |
190 | mutable uint : 1; |
191 | mutable uint , ; |
192 | QRect (QAction *) const; |
193 | |
194 | mutable QVector<QRect> ; |
195 | mutable QHash<QAction *, QWidget *> ; |
196 | void () const; |
197 | void (const QRect &screen) const; |
198 | QRect (const QWidget *widget) const; |
199 | QRect (int screen = -1) const; |
200 | mutable uint : 4; //4 bits is probably plenty |
201 | uint : 1; |
202 | QSize (const QRect & screen); |
203 | int () const; |
204 | |
205 | bool ; |
206 | |
207 | //selection |
208 | static QMenu *; |
209 | QPoint ; |
210 | uint : 1; |
211 | uint : 1; |
212 | int ; |
213 | QAction *; |
214 | #ifdef QT_KEYPAD_NAVIGATION |
215 | QAction *selectAction; |
216 | QAction *cancelAction; |
217 | #endif |
218 | QBasicTimer ; |
219 | enum { |
220 | , |
221 | |
222 | }; |
223 | QWidget *() const; |
224 | QAction *(QPoint p) const; |
225 | void (); |
226 | void (QAction *, int = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false); |
227 | void (QAction *, int, bool); |
228 | void (); |
229 | |
230 | //scrolling support |
231 | struct { |
232 | enum { , , , }; |
233 | enum { =0, =0x01, =0x02 }; |
234 | uint : 2, : 2; |
235 | int ; |
236 | QBasicTimer ; |
237 | |
238 | () : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { } |
239 | () { } |
240 | } *; |
241 | void (QMenuScroller::ScrollLocation location, bool active=false); |
242 | void (QMenuScroller::ScrollDirection direction, bool page=false, bool active=false); |
243 | void (QAction *action, QMenuScroller::ScrollLocation location, bool active=false); |
244 | |
245 | //synchronous operation (ie exec()) |
246 | QEventLoop *; |
247 | QPointer<QAction> ; |
248 | |
249 | //search buffer |
250 | QString ; |
251 | QBasicTimer ; |
252 | |
253 | //passing of mouse events up the parent hierarchy |
254 | QPointer<QMenu> ; |
255 | bool (QMouseEvent *); |
256 | |
257 | //used to walk up the popup list |
258 | struct { |
259 | QPointer<QWidget> ; |
260 | QPointer<QAction> ; |
261 | }; |
262 | virtual QList<QPointer<QWidget> > () const; |
263 | QMenuCaused ; |
264 | void (); |
265 | void (QMenu *, bool justRegister = false); |
266 | |
267 | //index mappings |
268 | inline QAction *(int i) const { return q_func()->actions().at(i); } |
269 | inline int (QAction *act) const { return q_func()->actions().indexOf(act); } |
270 | |
271 | //tear off support |
272 | uint : 1, : 1, : 1; |
273 | QPointer<QTornOffMenu> ; |
274 | |
275 | mutable bool ; |
276 | |
277 | //sloppy selection |
278 | int ; |
279 | mutable QAction *; |
280 | QRegion ; |
281 | |
282 | //default action |
283 | QPointer<QAction> ; |
284 | |
285 | QAction *; |
286 | QAction *; |
287 | |
288 | void (QAction *); |
289 | void (); |
290 | |
291 | //firing of events |
292 | void (QAction *, QAction::ActionEvent, bool self=true); |
293 | void (const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool); |
294 | |
295 | void (); |
296 | void (); |
297 | |
298 | bool (const QPoint &globalPos); |
299 | |
300 | void (); |
301 | |
302 | //menu fading/scrolling effects |
303 | bool ; |
304 | |
305 | #ifdef Q_WS_MAC |
306 | //mac menu binding |
307 | struct QMacMenuPrivate { |
308 | QList<QMacMenuAction*> actionItems; |
309 | OSMenuRef menu; |
310 | QMacMenuPrivate(); |
311 | ~QMacMenuPrivate(); |
312 | |
313 | bool merged(const QAction *action) const; |
314 | void addAction(QAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0); |
315 | void addAction(QMacMenuAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0); |
316 | void syncAction(QMacMenuAction *); |
317 | inline void syncAction(QAction *a) { syncAction(findAction(a)); } |
318 | void removeAction(QMacMenuAction *); |
319 | inline void removeAction(QAction *a) { removeAction(findAction(a)); } |
320 | inline QMacMenuAction *findAction(QAction *a) { |
321 | for(int i = 0; i < actionItems.size(); i++) { |
322 | QMacMenuAction *act = actionItems[i]; |
323 | if(a == act->action) |
324 | return act; |
325 | } |
326 | return 0; |
327 | } |
328 | } *mac_menu; |
329 | OSMenuRef macMenu(OSMenuRef merge); |
330 | #ifndef QT_MAC_USE_COCOA |
331 | void setMacMenuEnabled(bool enable = true); |
332 | #endif |
333 | void syncSeparatorsCollapsible(bool collapsible); |
334 | static QHash<OSMenuRef, OSMenuRef> mergeMenuHash; |
335 | static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash; |
336 | #endif |
337 | |
338 | QPointer<QAction> ; |
339 | #ifdef QT3_SUPPORT |
340 | bool ; |
341 | #endif |
342 | |
343 | #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR) |
344 | struct QWceMenuPrivate { |
345 | QList<QWceMenuAction*> actionItems; |
346 | HMENU menuHandle; |
347 | QWceMenuPrivate(); |
348 | ~QWceMenuPrivate(); |
349 | void addAction(QAction *, QWceMenuAction* =0); |
350 | void addAction(QWceMenuAction *, QWceMenuAction* =0); |
351 | void syncAction(QWceMenuAction *); |
352 | inline void syncAction(QAction *a) { syncAction(findAction(a)); } |
353 | void removeAction(QWceMenuAction *); |
354 | void rebuild(); |
355 | inline void removeAction(QAction *a) { removeAction(findAction(a)); } |
356 | inline QWceMenuAction *findAction(QAction *a) { |
357 | for(int i = 0; i < actionItems.size(); i++) { |
358 | QWceMenuAction *act = actionItems[i]; |
359 | if(a == act->action) |
360 | return act; |
361 | } |
362 | return 0; |
363 | } |
364 | } *wce_menu; |
365 | HMENU wceMenu(); |
366 | QAction* wceCommands(uint command); |
367 | #endif |
368 | #if defined(Q_WS_S60) |
369 | struct QSymbianMenuPrivate { |
370 | QList<QSymbianMenuAction*> actionItems; |
371 | QSymbianMenuPrivate(); |
372 | ~QSymbianMenuPrivate(); |
373 | void addAction(QAction *, QSymbianMenuAction* =0); |
374 | void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0); |
375 | void syncAction(QSymbianMenuAction *); |
376 | inline void syncAction(QAction *a) { syncAction(findAction(a)); } |
377 | void removeAction(QSymbianMenuAction *); |
378 | void rebuild(bool reCreate = false); |
379 | inline void removeAction(QAction *a) { removeAction(findAction(a)); } |
380 | inline QSymbianMenuAction *findAction(QAction *a) { |
381 | for(int i = 0; i < actionItems.size(); i++) { |
382 | QSymbianMenuAction *act = actionItems[i]; |
383 | if(a == act->action) |
384 | return act; |
385 | } |
386 | return 0; |
387 | } |
388 | } *symbian_menu; |
389 | #endif |
390 | QPointer<QWidget> ; |
391 | }; |
392 | |
393 | #endif // QT_NO_MENU |
394 | |
395 | QT_END_NAMESPACE |
396 | |
397 | #endif // QMENU_P_H |
398 | |