src/gui/widgets/qmenu_p.h
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    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 "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_show_toplevel(CEikMenuPane* menuPane);
       
    75 void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
       
    76 #endif // Q_WS_S60
       
    77 
       
    78 class QTornOffMenu;
       
    79 class QEventLoop;
       
    80 
       
    81 #ifdef Q_WS_MAC
       
    82 #  ifdef __OBJC__
       
    83 QT_END_NAMESPACE
       
    84 @class NSMenuItem;
       
    85 QT_BEGIN_NAMESPACE
       
    86 #  else
       
    87 typedef void NSMenuItem;
       
    88 #  endif //__OBJC__
       
    89 struct 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 
       
   111 struct 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 };
       
   122 typedef QList<QMenuMergeItem> QMenuMergeList;
       
   123 #endif
       
   124 
       
   125 #ifdef Q_WS_WINCE
       
   126 struct 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
       
   134 struct QSymbianMenuAction {
       
   135     uint command;
       
   136     int parent;
       
   137     CEikMenuPane* menuPane;
       
   138     QPointer<QAction> action;
       
   139     QSymbianMenuAction() : command(0) {}
       
   140 };
       
   141 #endif
       
   142 
       
   143 class QMenuPrivate : public QWidgetPrivate
       
   144 {
       
   145     Q_DECLARE_PUBLIC(QMenu)
       
   146 public:
       
   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     int scrollerHeight() const;
       
   186 
       
   187     //item calculations
       
   188     mutable uint itemsDirty : 1;
       
   189     mutable uint maxIconWidth, tabWidth;
       
   190     QRect actionRect(QAction *) const;
       
   191 
       
   192     mutable QVector<QRect> actionRects;
       
   193     mutable QWidgetList widgetItems;
       
   194     void updateActionRects() const;
       
   195     QRect popupGeometry(const QWidget *widget) const;
       
   196     QRect popupGeometry(int screen = -1) const;
       
   197     mutable uint ncols : 4; //4 bits is probably plenty
       
   198     uint collapsibleSeparators : 1;
       
   199 
       
   200     bool activationRecursionGuard;
       
   201 
       
   202     //selection
       
   203     static QPointer<QMenu> mouseDown;
       
   204     QPoint mousePopupPos;
       
   205     uint hasHadMouse : 1;
       
   206     uint aboutToHide : 1;
       
   207     int motions;
       
   208     QAction *currentAction;
       
   209 #ifdef QT_KEYPAD_NAVIGATION
       
   210     QAction *selectAction;
       
   211     QAction *cancelAction;
       
   212 #endif
       
   213     static QBasicTimer menuDelayTimer;
       
   214     enum SelectionReason {
       
   215         SelectedFromKeyboard,
       
   216         SelectedFromElsewhere
       
   217     };
       
   218     QAction *actionAt(QPoint p) const;
       
   219     void setFirstActionActive();
       
   220     void setCurrentAction(QAction *, int popup = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false);
       
   221     void popupAction(QAction *, int, bool);
       
   222     void setSyncAction();
       
   223 
       
   224     //scrolling support
       
   225     struct QMenuScroller {
       
   226         enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter };
       
   227         enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
       
   228         uint scrollFlags : 2, scrollDirection : 2;
       
   229         int scrollOffset;
       
   230         QBasicTimer scrollTimer;
       
   231 
       
   232         QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
       
   233         ~QMenuScroller() { }
       
   234     } *scroll;
       
   235     void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
       
   236     void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false);
       
   237     void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false);
       
   238 
       
   239     //synchronous operation (ie exec())
       
   240     QEventLoop *eventLoop;
       
   241     QPointer<QAction> syncAction;
       
   242 
       
   243     //search buffer
       
   244     QString searchBuffer;
       
   245     QBasicTimer searchBufferTimer;
       
   246 
       
   247     //passing of mouse events up the parent hierarchy
       
   248     QPointer<QMenu> activeMenu;
       
   249     bool mouseEventTaken(QMouseEvent *);
       
   250 
       
   251     //used to walk up the popup list
       
   252     struct QMenuCaused {
       
   253         QPointer<QWidget> widget;
       
   254         QPointer<QAction> action;
       
   255     };
       
   256     virtual QList<QPointer<QWidget> > calcCausedStack() const;
       
   257     QMenuCaused causedPopup;
       
   258     void hideUpToMenuBar();
       
   259     void hideMenu(QMenu *menu, bool justRegister = false);
       
   260 
       
   261     //index mappings
       
   262     inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }
       
   263     inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }
       
   264 
       
   265     //tear off support
       
   266     uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1;
       
   267     QPointer<QTornOffMenu> tornPopup;
       
   268 
       
   269     mutable bool hasCheckableItems;
       
   270 
       
   271     //sloppy selection
       
   272     static QBasicTimer sloppyDelayTimer;
       
   273     mutable QAction *sloppyAction;
       
   274     QRegion sloppyRegion;
       
   275 
       
   276     //default action
       
   277     QPointer<QAction> defaultAction;
       
   278 
       
   279     QAction *menuAction;
       
   280     QAction *defaultMenuAction;
       
   281 
       
   282     void setOverrideMenuAction(QAction *);
       
   283     void _q_overrideMenuActionDestroyed();
       
   284 
       
   285     //firing of events
       
   286     void activateAction(QAction *, QAction::ActionEvent, bool self=true);
       
   287     void activateCausedStack(const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool);
       
   288 
       
   289     void _q_actionTriggered();
       
   290     void _q_actionHovered();
       
   291 
       
   292     bool hasMouseMoved(const QPoint &globalPos);
       
   293 
       
   294     //menu fading/scrolling effects
       
   295     bool doChildEffects;
       
   296 
       
   297 #ifdef Q_WS_MAC
       
   298     //mac menu binding
       
   299     struct QMacMenuPrivate {
       
   300         QList<QMacMenuAction*> actionItems;
       
   301         OSMenuRef menu;
       
   302         QMacMenuPrivate();
       
   303         ~QMacMenuPrivate();
       
   304 
       
   305         bool merged(const QAction *action) const;
       
   306         void addAction(QAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0);
       
   307         void addAction(QMacMenuAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0);
       
   308         void syncAction(QMacMenuAction *);
       
   309         inline void syncAction(QAction *a) { syncAction(findAction(a)); }
       
   310         void removeAction(QMacMenuAction *);
       
   311         inline void removeAction(QAction *a) { removeAction(findAction(a)); }
       
   312         inline QMacMenuAction *findAction(QAction *a) {
       
   313             for(int i = 0; i < actionItems.size(); i++) {
       
   314                 QMacMenuAction *act = actionItems[i];
       
   315                 if(a == act->action)
       
   316                     return act;
       
   317             }
       
   318             return 0;
       
   319         }
       
   320     } *mac_menu;
       
   321     OSMenuRef macMenu(OSMenuRef merge);
       
   322     void setMacMenuEnabled(bool enable = true);
       
   323     void syncSeparatorsCollapsible(bool collapsible);
       
   324     static QHash<OSMenuRef, OSMenuRef> mergeMenuHash;
       
   325     static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash;
       
   326 #endif
       
   327 
       
   328     QPointer<QAction> actionAboutToTrigger;
       
   329 #ifdef QT3_SUPPORT
       
   330     bool emitHighlighted;
       
   331 #endif
       
   332 
       
   333 #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
       
   334     struct QWceMenuPrivate {
       
   335         QList<QWceMenuAction*> actionItems;
       
   336         HMENU menuHandle;
       
   337         QWceMenuPrivate();
       
   338         ~QWceMenuPrivate();        
       
   339         void addAction(QAction *, QWceMenuAction* =0);
       
   340         void addAction(QWceMenuAction *, QWceMenuAction* =0);
       
   341         void syncAction(QWceMenuAction *);
       
   342         inline void syncAction(QAction *a) { syncAction(findAction(a)); }
       
   343         void removeAction(QWceMenuAction *);
       
   344         void rebuild(bool reCreate = false);
       
   345         inline void removeAction(QAction *a) { removeAction(findAction(a)); }
       
   346         inline QWceMenuAction *findAction(QAction *a) {
       
   347             for(int i = 0; i < actionItems.size(); i++) {
       
   348                 QWceMenuAction *act = actionItems[i];
       
   349                 if(a == act->action)
       
   350                     return act;
       
   351             }
       
   352             return 0;
       
   353         }
       
   354     } *wce_menu;
       
   355     HMENU wceMenu(bool create = false);
       
   356     QAction* wceCommands(uint command);
       
   357 #endif
       
   358 #if defined(Q_WS_S60)
       
   359     struct QSymbianMenuPrivate {
       
   360         QList<QSymbianMenuAction*> actionItems;
       
   361         QSymbianMenuPrivate();
       
   362         ~QSymbianMenuPrivate();
       
   363         void addAction(QAction *, QSymbianMenuAction* =0);
       
   364         void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
       
   365         void syncAction(QSymbianMenuAction *);
       
   366         inline void syncAction(QAction *a) { syncAction(findAction(a)); }
       
   367         void removeAction(QSymbianMenuAction *);
       
   368         void rebuild(bool reCreate = false);
       
   369         inline void removeAction(QAction *a) { removeAction(findAction(a)); }
       
   370         inline QSymbianMenuAction *findAction(QAction *a) {
       
   371             for(int i = 0; i < actionItems.size(); i++) {
       
   372                 QSymbianMenuAction *act = actionItems[i];
       
   373                 if(a == act->action)
       
   374                     return act;
       
   375             }
       
   376             return 0;
       
   377         }
       
   378     } *symbian_menu;
       
   379 #endif
       
   380     QPointer<QWidget> noReplayFor;
       
   381 };
       
   382 
       
   383 #endif // QT_NO_MENU
       
   384 
       
   385 QT_END_NAMESPACE
       
   386 
       
   387 #endif // QMENU_P_H