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

Last change on this file since 603 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 12.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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_show_toplevel(CEikMenuPane* menuPane);
75void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
76#endif // Q_WS_S60
77
78class QTornOffMenu;
79class QEventLoop;
80
81#ifdef Q_WS_MAC
82# ifdef __OBJC__
83QT_END_NAMESPACE
84@class NSMenuItem;
85QT_BEGIN_NAMESPACE
86# else
87typedef void NSMenuItem;
88# endif //__OBJC__
89struct QMacMenuAction {
90 QMacMenuAction()
91#ifndef QT_MAC_USE_COCOA
92 : command(0)
93#else
94 : menuItem(0)
95#endif
96 , ignore_accel(0), merged(0), menu(0)
97 {
98 }
99 ~QMacMenuAction();
100#ifndef QT_MAC_USE_COCOA
101 uint command;
102#else
103 NSMenuItem *menuItem;
104#endif
105 uchar ignore_accel : 1;
106 uchar merged : 1;
107 QPointer<QAction> action;
108 OSMenuRef menu;
109};
110
111struct QMenuMergeItem
112{
113#ifndef QT_MAC_USE_COCOA
114 inline QMenuMergeItem(MenuCommand c, QMacMenuAction *a) : command(c), action(a) { }
115 MenuCommand command;
116#else
117 inline QMenuMergeItem(NSMenuItem *c, QMacMenuAction *a) : menuItem(c), action(a) { }
118 NSMenuItem *menuItem;
119#endif
120 QMacMenuAction *action;
121};
122typedef QList<QMenuMergeItem> QMenuMergeList;
123#endif
124
125#ifdef Q_WS_WINCE
126struct QWceMenuAction {
127 uint command;
128 QPointer<QAction> action;
129 HMENU menuHandle;
130 QWceMenuAction() : menuHandle(0), command(0) {}
131};
132#endif
133#ifdef Q_WS_S60
134struct QSymbianMenuAction {
135 uint command;
136 int parent;
137 CEikMenuPane* menuPane;
138 QPointer<QAction> action;
139 QSymbianMenuAction() : command(0) {}
140};
141#endif
142
143class QMenuPrivate : public QWidgetPrivate
144{
145 Q_DECLARE_PUBLIC(QMenu)
146public:
147 QMenuPrivate() : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0),
148 collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0),
149 currentAction(0),
150#ifdef QT_KEYPAD_NAVIGATION
151 selectAction(0),
152 cancelAction(0),
153#endif
154 scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
155 hasCheckableItems(0), sloppyAction(0), doChildEffects(false)
156#ifdef Q_WS_MAC
157 ,mac_menu(0)
158#endif
159#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
160 ,wce_menu(0)
161#endif
162#ifdef Q_WS_S60
163 ,symbian_menu(0)
164#endif
165#ifdef QT3_SUPPORT
166 ,emitHighlighted(false)
167#endif
168 { }
169 ~QMenuPrivate()
170 {
171 delete scroll;
172#ifdef Q_WS_MAC
173 delete mac_menu;
174#endif
175#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
176 delete wce_menu;
177#endif
178#ifdef Q_WS_S60
179 delete symbian_menu;
180#endif
181
182 }
183 void init();
184
185 static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
186 int scrollerHeight() const;
187
188 //item calculations
189 mutable uint itemsDirty : 1;
190 mutable uint maxIconWidth, tabWidth;
191 QRect actionRect(QAction *) const;
192
193 mutable QVector<QRect> actionRects;
194 mutable QHash<QAction *, QWidget *> widgetItems;
195 void updateActionRects() const;
196 QRect popupGeometry(const QWidget *widget) const;
197 QRect popupGeometry(int screen = -1) const;
198 mutable uint ncols : 4; //4 bits is probably plenty
199 uint collapsibleSeparators : 1;
200
201 bool activationRecursionGuard;
202
203 //selection
204 static QPointer<QMenu> mouseDown;
205 QPoint mousePopupPos;
206 uint hasHadMouse : 1;
207 uint aboutToHide : 1;
208 int motions;
209 QAction *currentAction;
210#ifdef QT_KEYPAD_NAVIGATION
211 QAction *selectAction;
212 QAction *cancelAction;
213#endif
214 static QBasicTimer menuDelayTimer;
215 enum SelectionReason {
216 SelectedFromKeyboard,
217 SelectedFromElsewhere
218 };
219 QWidget *topCausedWidget() const;
220 QAction *actionAt(QPoint p) const;
221 void setFirstActionActive();
222 void setCurrentAction(QAction *, int popup = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false);
223 void popupAction(QAction *, int, bool);
224 void setSyncAction();
225
226 //scrolling support
227 struct QMenuScroller {
228 enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter };
229 enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
230 uint scrollFlags : 2, scrollDirection : 2;
231 int scrollOffset;
232 QBasicTimer scrollTimer;
233
234 QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
235 ~QMenuScroller() { }
236 } *scroll;
237 void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
238 void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false);
239 void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false);
240
241 //synchronous operation (ie exec())
242 QEventLoop *eventLoop;
243 QPointer<QAction> syncAction;
244
245 //search buffer
246 QString searchBuffer;
247 QBasicTimer searchBufferTimer;
248
249 //passing of mouse events up the parent hierarchy
250 QPointer<QMenu> activeMenu;
251 bool mouseEventTaken(QMouseEvent *);
252
253 //used to walk up the popup list
254 struct QMenuCaused {
255 QPointer<QWidget> widget;
256 QPointer<QAction> action;
257 };
258 virtual QList<QPointer<QWidget> > calcCausedStack() const;
259 QMenuCaused causedPopup;
260 void hideUpToMenuBar();
261 void hideMenu(QMenu *menu, bool justRegister = false);
262
263 //index mappings
264 inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }
265 inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }
266
267 //tear off support
268 uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1;
269 QPointer<QTornOffMenu> tornPopup;
270
271 mutable bool hasCheckableItems;
272
273 //sloppy selection
274 static QBasicTimer sloppyDelayTimer;
275 mutable QAction *sloppyAction;
276 QRegion sloppyRegion;
277
278 //default action
279 QPointer<QAction> defaultAction;
280
281 QAction *menuAction;
282 QAction *defaultMenuAction;
283
284 void setOverrideMenuAction(QAction *);
285 void _q_overrideMenuActionDestroyed();
286
287 //firing of events
288 void activateAction(QAction *, QAction::ActionEvent, bool self=true);
289 void activateCausedStack(const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool);
290
291 void _q_actionTriggered();
292 void _q_actionHovered();
293
294 bool hasMouseMoved(const QPoint &globalPos);
295
296 void updateLayoutDirection();
297
298
299 //menu fading/scrolling effects
300 bool doChildEffects;
301
302#ifdef Q_WS_MAC
303 //mac menu binding
304 struct QMacMenuPrivate {
305 QList<QMacMenuAction*> actionItems;
306 OSMenuRef menu;
307 QMacMenuPrivate();
308 ~QMacMenuPrivate();
309
310 bool merged(const QAction *action) const;
311 void addAction(QAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0);
312 void addAction(QMacMenuAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0);
313 void syncAction(QMacMenuAction *);
314 inline void syncAction(QAction *a) { syncAction(findAction(a)); }
315 void removeAction(QMacMenuAction *);
316 inline void removeAction(QAction *a) { removeAction(findAction(a)); }
317 inline QMacMenuAction *findAction(QAction *a) {
318 for(int i = 0; i < actionItems.size(); i++) {
319 QMacMenuAction *act = actionItems[i];
320 if(a == act->action)
321 return act;
322 }
323 return 0;
324 }
325 } *mac_menu;
326 OSMenuRef macMenu(OSMenuRef merge);
327 void setMacMenuEnabled(bool enable = true);
328 void syncSeparatorsCollapsible(bool collapsible);
329 static QHash<OSMenuRef, OSMenuRef> mergeMenuHash;
330 static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash;
331#endif
332
333 QPointer<QAction> actionAboutToTrigger;
334#ifdef QT3_SUPPORT
335 bool emitHighlighted;
336#endif
337
338#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
339 struct QWceMenuPrivate {
340 QList<QWceMenuAction*> actionItems;
341 HMENU menuHandle;
342 QWceMenuPrivate();
343 ~QWceMenuPrivate();
344 void addAction(QAction *, QWceMenuAction* =0);
345 void addAction(QWceMenuAction *, QWceMenuAction* =0);
346 void syncAction(QWceMenuAction *);
347 inline void syncAction(QAction *a) { syncAction(findAction(a)); }
348 void removeAction(QWceMenuAction *);
349 void rebuild(bool reCreate = false);
350 inline void removeAction(QAction *a) { removeAction(findAction(a)); }
351 inline QWceMenuAction *findAction(QAction *a) {
352 for(int i = 0; i < actionItems.size(); i++) {
353 QWceMenuAction *act = actionItems[i];
354 if(a == act->action)
355 return act;
356 }
357 return 0;
358 }
359 } *wce_menu;
360 HMENU wceMenu(bool create = false);
361 QAction* wceCommands(uint command);
362#endif
363#if defined(Q_WS_S60)
364 struct QSymbianMenuPrivate {
365 QList<QSymbianMenuAction*> actionItems;
366 QSymbianMenuPrivate();
367 ~QSymbianMenuPrivate();
368 void addAction(QAction *, QSymbianMenuAction* =0);
369 void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
370 void syncAction(QSymbianMenuAction *);
371 inline void syncAction(QAction *a) { syncAction(findAction(a)); }
372 void removeAction(QSymbianMenuAction *);
373 void rebuild(bool reCreate = false);
374 inline void removeAction(QAction *a) { removeAction(findAction(a)); }
375 inline QSymbianMenuAction *findAction(QAction *a) {
376 for(int i = 0; i < actionItems.size(); i++) {
377 QSymbianMenuAction *act = actionItems[i];
378 if(a == act->action)
379 return act;
380 }
381 return 0;
382 }
383 } *symbian_menu;
384#endif
385 QPointer<QWidget> noReplayFor;
386};
387
388#endif // QT_NO_MENU
389
390QT_END_NAMESPACE
391
392#endif // QMENU_P_H
Note: See TracBrowser for help on using the repository browser.