source: trunk/src/gui/widgets/qmenu_p.h@ 966

Last change on this file since 966 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 12.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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
65class 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
69QT_BEGIN_NAMESPACE
70
71#ifndef QT_NO_MENU
72
73#ifdef Q_WS_S60
74void qt_symbian_next_menu_from_action(QWidget* actionContainer);
75void qt_symbian_show_toplevel(CEikMenuPane* menuPane);
76void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
77#endif // Q_WS_S60
78
79class QTornOffMenu;
80class QEventLoop;
81
82#ifdef Q_WS_MAC
83# ifdef __OBJC__
84QT_END_NAMESPACE
85@class NSMenuItem;
86QT_BEGIN_NAMESPACE
87# else
88typedef void NSMenuItem;
89# endif //__OBJC__
90struct 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
112struct 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};
123typedef QList<QMenuMergeItem> QMenuMergeList;
124#endif
125
126#ifdef Q_WS_WINCE
127struct 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
135struct QSymbianMenuAction {
136 uint command;
137 int parent;
138 CEikMenuPane* menuPane;
139 QPointer<QAction> action;
140 QSymbianMenuAction() : command(0) {}
141};
142#endif
143
144class QMenuPrivate : public QWidgetPrivate
145{
146 Q_DECLARE_PUBLIC(QMenu)
147public:
148 QMenuPrivate() : 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), sloppyAction(0), doChildEffects(false)
157#ifdef Q_WS_MAC
158 ,mac_menu(0)
159#endif
160#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
161 ,wce_menu(0)
162#endif
163#ifdef Q_WS_S60
164 ,symbian_menu(0)
165#endif
166#ifdef QT3_SUPPORT
167 ,emitHighlighted(false)
168#endif
169 { }
170 ~QMenuPrivate()
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 init();
185
186 static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
187 int scrollerHeight() const;
188
189 //item calculations
190 mutable uint itemsDirty : 1;
191 mutable uint maxIconWidth, tabWidth;
192 QRect actionRect(QAction *) const;
193
194 mutable QVector<QRect> actionRects;
195 mutable QHash<QAction *, QWidget *> widgetItems;
196 void updateActionRects() const;
197 QRect popupGeometry(const QWidget *widget) const;
198 QRect popupGeometry(int screen = -1) const;
199 mutable uint ncols : 4; //4 bits is probably plenty
200 uint collapsibleSeparators : 1;
201
202 bool activationRecursionGuard;
203
204 //selection
205 static QMenu *mouseDown;
206 QPoint mousePopupPos;
207 uint hasHadMouse : 1;
208 uint aboutToHide : 1;
209 int motions;
210 QAction *currentAction;
211#ifdef QT_KEYPAD_NAVIGATION
212 QAction *selectAction;
213 QAction *cancelAction;
214#endif
215 QBasicTimer menuDelayTimer;
216 enum SelectionReason {
217 SelectedFromKeyboard,
218 SelectedFromElsewhere
219 };
220 QWidget *topCausedWidget() const;
221 QAction *actionAt(QPoint p) const;
222 void setFirstActionActive();
223 void setCurrentAction(QAction *, int popup = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false);
224 void popupAction(QAction *, int, bool);
225 void setSyncAction();
226
227 //scrolling support
228 struct QMenuScroller {
229 enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter };
230 enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
231 uint scrollFlags : 2, scrollDirection : 2;
232 int scrollOffset;
233 QBasicTimer scrollTimer;
234
235 QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
236 ~QMenuScroller() { }
237 } *scroll;
238 void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
239 void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false);
240 void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false);
241
242 //synchronous operation (ie exec())
243 QEventLoop *eventLoop;
244 QPointer<QAction> syncAction;
245
246 //search buffer
247 QString searchBuffer;
248 QBasicTimer searchBufferTimer;
249
250 //passing of mouse events up the parent hierarchy
251 QPointer<QMenu> activeMenu;
252 bool mouseEventTaken(QMouseEvent *);
253
254 //used to walk up the popup list
255 struct QMenuCaused {
256 QPointer<QWidget> widget;
257 QPointer<QAction> action;
258 };
259 virtual QList<QPointer<QWidget> > calcCausedStack() const;
260 QMenuCaused causedPopup;
261 void hideUpToMenuBar();
262 void hideMenu(QMenu *menu, bool justRegister = false);
263
264 //index mappings
265 inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }
266 inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }
267
268 //tear off support
269 uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1;
270 QPointer<QTornOffMenu> tornPopup;
271
272 mutable bool hasCheckableItems;
273
274 //sloppy selection
275 static int sloppyDelayTimer;
276 mutable QAction *sloppyAction;
277 QRegion sloppyRegion;
278
279 //default action
280 QPointer<QAction> defaultAction;
281
282 QAction *menuAction;
283 QAction *defaultMenuAction;
284
285 void setOverrideMenuAction(QAction *);
286 void _q_overrideMenuActionDestroyed();
287
288 //firing of events
289 void activateAction(QAction *, QAction::ActionEvent, bool self=true);
290 void activateCausedStack(const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool);
291
292 void _q_actionTriggered();
293 void _q_actionHovered();
294
295 bool hasMouseMoved(const QPoint &globalPos);
296
297 void updateLayoutDirection();
298
299
300 //menu fading/scrolling effects
301 bool doChildEffects;
302
303#ifdef Q_WS_MAC
304 //mac menu binding
305 struct QMacMenuPrivate {
306 QList<QMacMenuAction*> actionItems;
307 OSMenuRef menu;
308 QMacMenuPrivate();
309 ~QMacMenuPrivate();
310
311 bool merged(const QAction *action) const;
312 void addAction(QAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0);
313 void addAction(QMacMenuAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0);
314 void syncAction(QMacMenuAction *);
315 inline void syncAction(QAction *a) { syncAction(findAction(a)); }
316 void removeAction(QMacMenuAction *);
317 inline void removeAction(QAction *a) { removeAction(findAction(a)); }
318 inline QMacMenuAction *findAction(QAction *a) {
319 for(int i = 0; i < actionItems.size(); i++) {
320 QMacMenuAction *act = actionItems[i];
321 if(a == act->action)
322 return act;
323 }
324 return 0;
325 }
326 } *mac_menu;
327 OSMenuRef macMenu(OSMenuRef merge);
328 void setMacMenuEnabled(bool enable = true);
329 void syncSeparatorsCollapsible(bool collapsible);
330 static QHash<OSMenuRef, OSMenuRef> mergeMenuHash;
331 static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash;
332#endif
333
334 QPointer<QAction> actionAboutToTrigger;
335#ifdef QT3_SUPPORT
336 bool emitHighlighted;
337#endif
338
339#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
340 struct QWceMenuPrivate {
341 QList<QWceMenuAction*> actionItems;
342 HMENU menuHandle;
343 QWceMenuPrivate();
344 ~QWceMenuPrivate();
345 void addAction(QAction *, QWceMenuAction* =0);
346 void addAction(QWceMenuAction *, QWceMenuAction* =0);
347 void syncAction(QWceMenuAction *);
348 inline void syncAction(QAction *a) { syncAction(findAction(a)); }
349 void removeAction(QWceMenuAction *);
350 void rebuild();
351 inline void removeAction(QAction *a) { removeAction(findAction(a)); }
352 inline QWceMenuAction *findAction(QAction *a) {
353 for(int i = 0; i < actionItems.size(); i++) {
354 QWceMenuAction *act = actionItems[i];
355 if(a == act->action)
356 return act;
357 }
358 return 0;
359 }
360 } *wce_menu;
361 HMENU wceMenu();
362 QAction* wceCommands(uint command);
363#endif
364#if defined(Q_WS_S60)
365 struct QSymbianMenuPrivate {
366 QList<QSymbianMenuAction*> actionItems;
367 QSymbianMenuPrivate();
368 ~QSymbianMenuPrivate();
369 void addAction(QAction *, QSymbianMenuAction* =0);
370 void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
371 void syncAction(QSymbianMenuAction *);
372 inline void syncAction(QAction *a) { syncAction(findAction(a)); }
373 void removeAction(QSymbianMenuAction *);
374 void rebuild(bool reCreate = false);
375 inline void removeAction(QAction *a) { removeAction(findAction(a)); }
376 inline QSymbianMenuAction *findAction(QAction *a) {
377 for(int i = 0; i < actionItems.size(); i++) {
378 QSymbianMenuAction *act = actionItems[i];
379 if(a == act->action)
380 return act;
381 }
382 return 0;
383 }
384 } *symbian_menu;
385#endif
386 QPointer<QWidget> noReplayFor;
387};
388
389#endif // QT_NO_MENU
390
391QT_END_NAMESPACE
392
393#endif // QMENU_P_H
Note: See TracBrowser for help on using the repository browser.