Fixed crash in GL 2 paint engine on Intel Atom.
[profile/ivi/qtbase.git] / src / widgets / widgets / qmenu_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
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 "QtWidgets/qmenubar.h"
57 #include "QtWidgets/qstyleoption.h"
58 #ifdef Q_OS_MAC
59 #include "QtWidgets/qmacdefines_mac.h"
60 #endif
61 #include "QtCore/qdatetime.h"
62 #include "QtCore/qmap.h"
63 #include "QtCore/qhash.h"
64 #include "QtCore/qbasictimer.h"
65 #include "private/qwidget_p.h"
66
67
68 #ifdef Q_WS_S60
69 class CEikMenuPane;
70 #define QT_SYMBIAN_FIRST_MENU_ITEM 32000
71 #define QT_SYMBIAN_LAST_MENU_ITEM 41999 // 10000 items ought to be enough for anybody...
72 #endif
73 QT_BEGIN_NAMESPACE
74
75 #ifndef QT_NO_MENU
76
77 #ifdef Q_WS_S60
78 void qt_symbian_next_menu_from_action(QWidget* actionContainer);
79 void qt_symbian_show_toplevel(CEikMenuPane* menuPane);
80 void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
81 #endif // Q_WS_S60
82
83 class QTornOffMenu;
84 class QEventLoop;
85
86 #ifdef Q_WS_WINCE
87 struct QWceMenuAction {
88     uint command;
89     QPointer<QAction> action;
90     HMENU menuHandle;
91     QWceMenuAction() : menuHandle(0), command(0) {}
92 };
93 #endif
94 #ifdef Q_WS_S60
95 struct QSymbianMenuAction {
96     uint command;
97     int parent;
98     CEikMenuPane* menuPane;
99     QPointer<QAction> action;
100     QSymbianMenuAction() : command(0) {}
101 };
102 #endif
103
104 class QMenuPrivate : public QWidgetPrivate
105 {
106     Q_DECLARE_PUBLIC(QMenu)
107 public:
108     QMenuPrivate() : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0),
109                       collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0),
110                       currentAction(0),
111 #ifdef QT_KEYPAD_NAVIGATION
112                       selectAction(0),
113                       cancelAction(0),
114 #endif
115                       scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
116                       hasCheckableItems(0), sloppyAction(0), doChildEffects(false), platformMenu(0)
117
118 #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
119                       ,wce_menu(0)
120 #endif
121 #ifdef Q_WS_S60
122                       ,symbian_menu(0)
123 #endif
124     { }
125     ~QMenuPrivate()
126     {
127         delete scroll;
128         delete platformMenu;
129 #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
130         delete wce_menu;
131 #endif
132 #ifdef Q_WS_S60
133         delete symbian_menu;
134 #endif
135
136     }
137     void init();
138
139     static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
140     int scrollerHeight() const;
141
142     //item calculations
143     mutable uint itemsDirty : 1;
144     mutable uint maxIconWidth, tabWidth;
145     QRect actionRect(QAction *) const;
146
147     mutable QVector<QRect> actionRects;
148     mutable QHash<QAction *, QWidget *> widgetItems;
149     void updateActionRects() const;
150     void updateActionRects(const QRect &screen) const;
151     QRect popupGeometry(const QWidget *widget) const;
152     QRect popupGeometry(int screen = -1) const;
153     mutable uint ncols : 4; //4 bits is probably plenty
154     uint collapsibleSeparators : 1;
155     QSize adjustMenuSizeForScreen(const QRect & screen);
156     int getLastVisibleAction() const;
157
158     bool activationRecursionGuard;
159
160     //selection
161     static QMenu *mouseDown;
162     QPoint mousePopupPos;
163     uint hasHadMouse : 1;
164     uint aboutToHide : 1;
165     int motions;
166     QAction *currentAction;
167 #ifdef QT_KEYPAD_NAVIGATION
168     QAction *selectAction;
169     QAction *cancelAction;
170 #endif
171     QBasicTimer menuDelayTimer;
172     enum SelectionReason {
173         SelectedFromKeyboard,
174         SelectedFromElsewhere
175     };
176     QWidget *topCausedWidget() const;
177     QAction *actionAt(QPoint p) const;
178     void setFirstActionActive();
179     void setCurrentAction(QAction *, int popup = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false);
180     void popupAction(QAction *, int, bool);
181     void setSyncAction();
182
183     //scrolling support
184     struct QMenuScroller {
185         enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter };
186         enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
187         uint scrollFlags : 2, scrollDirection : 2;
188         int scrollOffset;
189         QBasicTimer scrollTimer;
190
191         QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
192         ~QMenuScroller() { }
193     } *scroll;
194     void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
195     void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false);
196     void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false);
197
198     //synchronous operation (ie exec())
199     QEventLoop *eventLoop;
200     QPointer<QAction> syncAction;
201
202     //search buffer
203     QString searchBuffer;
204     QBasicTimer searchBufferTimer;
205
206     //passing of mouse events up the parent hierarchy
207     QPointer<QMenu> activeMenu;
208     bool mouseEventTaken(QMouseEvent *);
209
210     //used to walk up the popup list
211     struct QMenuCaused {
212         QPointer<QWidget> widget;
213         QPointer<QAction> action;
214     };
215     virtual QList<QPointer<QWidget> > calcCausedStack() const;
216     QMenuCaused causedPopup;
217     void hideUpToMenuBar();
218     void hideMenu(QMenu *menu, bool justRegister = false);
219
220     //index mappings
221     inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }
222     inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }
223
224     //tear off support
225     uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1;
226     QPointer<QTornOffMenu> tornPopup;
227
228     mutable bool hasCheckableItems;
229
230     //sloppy selection
231     static int sloppyDelayTimer;
232     mutable QAction *sloppyAction;
233     QRegion sloppyRegion;
234
235     //default action
236     QPointer<QAction> defaultAction;
237
238     QAction *menuAction;
239     QAction *defaultMenuAction;
240
241     void setOverrideMenuAction(QAction *);
242     void _q_overrideMenuActionDestroyed();
243
244     //firing of events
245     void activateAction(QAction *, QAction::ActionEvent, bool self=true);
246     void activateCausedStack(const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool);
247
248     void _q_actionTriggered();
249     void _q_actionHovered();
250
251     bool hasMouseMoved(const QPoint &globalPos);
252
253     void updateLayoutDirection();
254
255     //menu fading/scrolling effects
256     bool doChildEffects;
257
258     QPlatformMenu *platformMenu;
259
260     QPointer<QAction> actionAboutToTrigger;
261
262 #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
263     struct QWceMenuPrivate {
264         QList<QWceMenuAction*> actionItems;
265         HMENU menuHandle;
266         QWceMenuPrivate();
267         ~QWceMenuPrivate();
268         void addAction(QAction *, QWceMenuAction* =0);
269         void addAction(QWceMenuAction *, QWceMenuAction* =0);
270         void syncAction(QWceMenuAction *);
271         inline void syncAction(QAction *a) { syncAction(findAction(a)); }
272         void removeAction(QWceMenuAction *);
273         void rebuild();
274         inline void removeAction(QAction *a) { removeAction(findAction(a)); }
275         inline QWceMenuAction *findAction(QAction *a) {
276             for(int i = 0; i < actionItems.size(); i++) {
277                 QWceMenuAction *act = actionItems[i];
278                 if(a == act->action)
279                     return act;
280             }
281             return 0;
282         }
283     } *wce_menu;
284     HMENU wceMenu();
285     QAction* wceCommands(uint command);
286 #endif
287 #if defined(Q_WS_S60)
288     struct QSymbianMenuPrivate {
289         QList<QSymbianMenuAction*> actionItems;
290         QSymbianMenuPrivate();
291         ~QSymbianMenuPrivate();
292         void addAction(QAction *, QSymbianMenuAction* =0);
293         void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
294         void syncAction(QSymbianMenuAction *);
295         inline void syncAction(QAction *a) { syncAction(findAction(a)); }
296         void removeAction(QSymbianMenuAction *);
297         void rebuild(bool reCreate = false);
298         inline void removeAction(QAction *a) { removeAction(findAction(a)); }
299         inline QSymbianMenuAction *findAction(QAction *a) {
300             for(int i = 0; i < actionItems.size(); i++) {
301                 QSymbianMenuAction *act = actionItems[i];
302                 if(a == act->action)
303                     return act;
304             }
305             return 0;
306         }
307     } *symbian_menu;
308 #endif
309     QPointer<QWidget> noReplayFor;
310 };
311
312 #endif // QT_NO_MENU
313
314 QT_END_NAMESPACE
315
316 #endif // QMENU_P_H