Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/widgets/qmenubar.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6868#include "qdebug.h"
    6969
    70 #ifdef Q_OS_WINCE
     70#ifdef Q_WS_WINCE
    7171extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp
    7272#endif
     
    117117QAction *QMenuBarPrivate::actionAt(QPoint p) const
    118118{
    119     Q_Q(const QMenuBar);
    120     QList<QAction*> items = q->actions();
    121     for(int i = 0; i < items.size(); ++i) {
    122         if(actionRect(items.at(i)).contains(p))
    123             return items.at(i);
     119    for(int i = 0; i < actions.size(); ++i) {
     120        if(actionRect(actions.at(i)).contains(p))
     121            return actions.at(i);
    124122    }
    125123    return 0;
     
    135133
    136134    if (extVisible) {
    137         if (q->layoutDirection() == Qt::RightToLeft)
     135        if (q->isRightToLeft())
    138136            result.setLeft(result.left() + extension->sizeHint().width());
    139137        else
     
    143141    if (leftWidget && leftWidget->isVisible()) {
    144142        QSize sz = leftWidget->sizeHint();
    145         if (q->layoutDirection() == Qt::RightToLeft)
     143        if (q->isRightToLeft())
    146144            result.setRight(result.right() - sz.width());
    147145        else
     
    151149    if (rightWidget && rightWidget->isVisible()) {
    152150        QSize sz = rightWidget->sizeHint();
    153         if (q->layoutDirection() == Qt::RightToLeft)
     151        if (q->isRightToLeft())
    154152            result.setLeft(result.left() + sz.width());
    155153        else
     
    195193
    196194#ifdef Q_WS_MAC
    197     if(mac_menubar) {//nothing to see here folks, move along..
     195    if(q->isNativeMenuBar()) {//nothing to see here folks, move along..
    198196        itemsDirty = false;
    199197        return;
    200198    }
    201199#endif
    202     calcActionRects(q_width, q_start, actionRects, actionList);
    203     itemsWidth = q_width;
    204     itemsStart = q_start;
     200    calcActionRects(q_width, q_start);
    205201    currentAction = 0;
    206202#ifndef QT_NO_SHORTCUT
     
    209205            q->releaseShortcut(shortcutIndexMap.value(j));
    210206        shortcutIndexMap.resize(0); // faster than clear
    211         for(int i = 0; i < actionList.count(); i++)
    212             shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actionList.at(i)->text())));
     207        for(int i = 0; i < actions.count(); i++)
     208            shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text())));
    213209    }
    214210#endif
     
    221217    //we try to see if the actions will fit there
    222218    bool hasHiddenActions = false;
    223     foreach(QAction *action, actionList) {
    224         if (!menuRect.contains(actionRect(action))) {
     219    for (int i = 0; i < actions.count(); ++i) {
     220        const QRect &rect = actionRects.at(i);
     221        if (rect.isValid() && !menuRect.contains(rect)) {
    225222            hasHiddenActions = true;
    226223            break;
     
    231228    if (hasHiddenActions) {
    232229        menuRect = this->menuRect(true);
    233         foreach(QAction *action, actionList) {
    234             if (!menuRect.contains(actionRect(action))) {
    235                 hiddenActions.append(action);
     230        for (int i = 0; i < actions.count(); ++i) {
     231            const QRect &rect = actionRects.at(i);
     232            if (rect.isValid() && !menuRect.contains(rect)) {
     233                hiddenActions.append(actions.at(i));
    236234            }
    237235        }
     
    248246
    249247        int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q);
    250         int x = q->layoutDirection() == Qt::RightToLeft
     248        int x = q->isRightToLeft()
    251249                ? menuRect.left() - extension->sizeHint().width() + 1
    252250                : menuRect.right();
     
    258256    q->updateGeometry();
    259257#ifdef QT3_SUPPORT
    260     if (q->parentWidget() != 0) {
     258    if (parent) {
    261259        QMenubarUpdatedEvent menubarUpdated(q);
    262         QApplication::sendEvent(q->parentWidget(), &menubarUpdated);
     260        QApplication::sendEvent(parent, &menubarUpdated);
    263261    }
    264262#endif
     
    268266{
    269267    Q_Q(const QMenuBar);
    270     QRect ret = actionRects.value(act);
    271     const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
    272     ret.translate(fw, fw);
     268    const int index = actions.indexOf(act);
     269    if (index == -1)
     270        return QRect();
     271
     272    //makes sure the geometries are up-to-date
     273    const_cast<QMenuBarPrivate*>(this)->updateGeometries();
     274
     275    if (index >= actionRects.count())
     276        return QRect(); // that can happen in case of native menubar
     277
     278    QRect ret = actionRects.at(index);
    273279    return QStyle::visualRect(q->layoutDirection(), q->rect(), ret);
     280}
     281
     282void QMenuBarPrivate::focusFirstAction()
     283{
     284    if(!currentAction) {
     285        updateGeometries();
     286        int index = 0;
     287        while (index < actions.count() && actionRects.at(index).isNull()) ++index;
     288        if (index < actions.count())
     289            setCurrentAction(actions.at(index));
     290    }
    274291}
    275292
     
    283300    keyboardState = b;
    284301    if(b) {
    285         QWidget *fw = qApp->focusWidget();
     302        QWidget *fw = QApplication::focusWidget();
    286303        if (fw != q)
    287304            keyboardFocusWidget = fw;
    288         if(!currentAction && !actionList.isEmpty())
    289             setCurrentAction(actionList.first());
     305        focusFirstAction();
    290306        q->setFocus(Qt::MenuBarFocusReason);
    291307    } else {
     
    293309            setCurrentAction(0);
    294310        if(keyboardFocusWidget) {
    295             if (qApp->focusWidget() == q)
     311            if (QApplication::focusWidget() == q)
    296312                keyboardFocusWidget->setFocus(Qt::MenuBarFocusReason);
    297313            keyboardFocusWidget = 0;
     
    317333        QSize popup_size = activeMenu->sizeHint();
    318334
    319         QRect screenRect = QApplication::desktop()->screenGeometry(pos);
     335        //we put the popup menu on the screen containing the bottom-center of the action rect
     336        QRect screenRect = QApplication::desktop()->screenGeometry(pos + QPoint(adjustedActionRect.width() / 2, 0));
     337        pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
    320338
    321339        const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height());
    322340        const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
     341        const bool rtl = q->isRightToLeft();
    323342        const int actionWidth = adjustedActionRect.width();
    324343
    325344        if (!fitUp && !fitDown) { //we should shift the menu
    326             bool shouldShiftToRight = !q->isRightToLeft();
    327             if (q->isRightToLeft() && popup_size.width() > pos.x())
     345            bool shouldShiftToRight = !rtl;
     346            if (rtl && popup_size.width() > pos.x())
    328347                shouldShiftToRight = true;
    329348            else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())
    330349                shouldShiftToRight = false;
    331350
    332             if (shouldShiftToRight)
    333                 pos.rx() += actionWidth;
    334             else
    335                 pos.rx() -= popup_size.width();
    336         } else if (q->isRightToLeft()) {
    337             pos.setX(pos.x()-(popup_size.width() - actionWidth));
    338         }
    339 
    340         if(pos.x() < screenRect.x()) {
    341             pos.setX(screenRect.x());
    342         } else {
    343             const int off = pos.x()+popup_size.width() - screenRect.right();
    344             if(off > 0)
    345                 pos.setX(qMax(screenRect.x(), pos.x()-off));
    346 
     351            if (shouldShiftToRight) {
     352                pos.rx() += actionWidth + (rtl ? popup_size.width() : 0);
     353            } else {
     354                //shift to left
     355                if (!rtl)
     356                    pos.rx() -= popup_size.width();
     357            }
     358        } else if (rtl) {
     359            pos.rx() += actionWidth;
    347360        }
    348361
     
    399412}
    400413
    401 void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const
     414void QMenuBarPrivate::calcActionRects(int max_width, int start) const
    402415{
    403416    Q_Q(const QMenuBar);
    404417
    405     if(!itemsDirty && itemsWidth == max_width && itemsStart == start) {
    406         actionRects = actionRects;
    407         actionList = actionList;
     418    if(!itemsDirty)
    408419        return;
    409     }
    410     actionRects.clear();
    411     actionList.clear();
    412     const int itemSpacing = q->style()->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q);
     420
     421    //let's reinitialize the buffer
     422    actionRects.resize(actions.count());
     423    actionRects.fill(QRect());
     424
     425    const QStyle *style = q->style();
     426
     427    const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q);
    413428    int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0;
    414     QList<QAction*> items = q->actions();
    415429
    416430    //calculate size
    417431    const QFontMetrics fm = q->fontMetrics();
    418     const int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q),
    419               vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q),
    420                 icone = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
    421     for(int i = 0; i < items.count(); i++) {
    422         QAction *action = items.at(i);
     432    const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q),
     433              vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q),
     434                icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
     435    for(int i = 0; i < actions.count(); i++) {
     436        QAction *action = actions.at(i);
    423437        if(!action->isVisible())
    424438            continue;
     
    428442        //calc what I think the size is..
    429443        if(action->isSeparator()) {
    430             if (q->style()->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q))
    431                 separator = actionRects.count();
     444            if (style->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q))
     445                separator = i;
    432446            continue; //we don't really position these!
    433447        } else {
    434             QString s = action->text();
    435             if(!s.isEmpty()) {
    436                 int w = fm.width(s);
    437                 w -= s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&'));
    438                 w += s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&'));
    439                 sz = QSize(w, fm.height());
    440             }
    441 
     448            const QString s = action->text();
    442449            QIcon is = action->icon();
    443             if (!is.isNull()) {
    444                 QSize is_sz = QSize(icone, icone);
    445                 if (is_sz.height() > sz.height())
    446                     sz.setHeight(is_sz.height());
    447                 if (is_sz.width() > sz.width())
    448                     sz.setWidth(is_sz.width());
    449             }
     450            // If an icon is set, only the icon is visible
     451            if (!is.isNull())
     452                sz = sz.expandedTo(QSize(icone, icone));
     453            else if (!s.isEmpty())
     454                sz = fm.size(Qt::TextShowMnemonic, s);
    450455        }
    451456
     
    457462        if(!sz.isEmpty()) {
    458463            { //update the separator state
    459                 int iWidth = sz.width();
    460                 iWidth += itemSpacing;
     464                int iWidth = sz.width() + itemSpacing;
    461465                if(separator == -1)
    462466                    separator_start += iWidth;
     
    467471            max_item_height = qMax(max_item_height, sz.height());
    468472            //append
    469             actionRects.insert(action, QRect(0, 0, sz.width(), sz.height()));
    470             actionList.append(action);
     473            actionRects[i] = QRect(0, 0, sz.width(), sz.height());
    471474        }
    472475    }
    473476
    474477    //calculate position
    475     int x = ((start == -1) ? hmargin : start) + itemSpacing;
    476     int y = vmargin;
    477     for(int i = 0; i < actionList.count(); i++) {
    478         QAction *action = actionList.at(i);
    479         QRect &rect = actionRects[action];
     478    const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
     479    int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
     480    int y = fw + vmargin;
     481    for(int i = 0; i < actions.count(); i++) {
     482        QRect &rect = actionRects[i];
     483        if (rect.isNull())
     484            continue;
     485
    480486        //resize
    481487        rect.setHeight(max_item_height);
     
    533539#ifndef QT_NO_ACCESSIBILITY
    534540        if (QAccessible::isActive()) {
    535             QList<QAction*> actions = q->actions();
    536541            int actionIndex = actions.indexOf(action);
    537542            ++actionIndex;
     
    583588    \brief The QMenuBar class provides a horizontal menu bar.
    584589
    585     \ingroup application
    586     \mainclass
     590    \ingroup mainwindow-classes
    587591
    588592    A menu bar consists of a list of pull-down menu items. You add
     
    662666    \row \i about.*
    663667         \i Application Menu | About <application name>
    664          \i If this entry is not found no About item will appear in
    665             the Application Menu
     668         \i The application name is fetched from the \c {Info.plist} file
     669            (see note below). If this entry is not found no About item
     670            will appear in the Application Menu.
    666671    \row \i config, options, setup, settings or preferences
    667672         \i Application Menu | Preferences
     
    707712
    708713    The \l{mainwindows/menus}{Menus} example shows how to use QMenuBar
    709     and QMenu.  The other \l{Qt Examples#Main Windows}{main window
     714    and QMenu.  The other \l{Main Window Examples}{main window
    710715    application examples} also provide menus using these classes.
    711716
    712717    \sa QMenu, QShortcut, QAction,
    713         {http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/index.html}{Introduction to Apple Human Interface Guidelines},
     718        {http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGIntro/XHIGIntro.html}{Introduction to Apple Human Interface Guidelines},
    714719        {fowler}{GUI Design Handbook: Menu Bar}, {Menus Example}
    715720*/
     
    726731        q->hide();
    727732#endif
    728 #ifdef Q_OS_WINCE
     733#ifdef Q_WS_WINCE
    729734    if (qt_wince_is_mobile()) {
    730735        wceCreateMenuBar(q->parentWidget());
     
    732737            q->hide();
    733738    }
    734 #endif
     739    else {
     740        QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
     741    }
     742#endif
     743#ifdef Q_WS_S60
     744    symbianCreateMenuBar(q->parentWidget());
     745    if(symbian_menubar)
     746        q->hide();
     747#endif
     748
    735749    q->setBackgroundRole(QPalette::Button);
    736750    oldWindow = oldParent = 0;
     
    746760}
    747761
     762//Gets the next action for keyboard navigation
     763QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const
     764{
     765    Q_Q(const QMenuBar);
     766    const_cast<QMenuBarPrivate*>(this)->updateGeometries();
     767    bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q);
     768    const int start = (_start == -1 && increment == -1) ? actions.count() : _start;
     769    const int end =  increment == -1 ? 0 : actions.count() - 1;
     770
     771    for (int i = start; start != end;) {
     772        i += increment;
     773        QAction *current = actions.at(i);
     774        if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled()))
     775            return current;
     776    }
     777
     778    if (_start != -1) //let's try from the beginning or the end
     779        return getNextAction(-1, increment);
     780
     781    return 0;
     782}
     783
    748784/*!
    749785    Constructs a menu bar with parent \a parent.
     
    777813    d->macDestroyMenuBar();
    778814#endif
    779 #ifdef Q_OS_WINCE
     815#ifdef Q_WS_WINCE
    780816    Q_D(QMenuBar);
    781817    if (qt_wince_is_mobile())
    782818        d->wceDestroyMenuBar();
     819#endif
     820#ifdef Q_WS_S60
     821    Q_D(QMenuBar);
     822    d->symbianDestroyMenuBar();
    783823#endif
    784824}
     
    925965    Removes all the actions from the menu bar.
    926966
     967    \note On Mac OS X, menu items that have been merged to the system
     968    menu bar are not removed by this function. One way to handle this
     969    would be to remove the extra actions yourself. You can set the
     970    \l{QAction::MenuRole}{menu role} on the different menus, so that
     971    you know ahead of time which menu items get merged and which do
     972    not. Then decide what to recreate or remove yourself.
     973
    927974    \sa removeAction()
    928975*/
     
    9781025
    9791026    //draw the items
    980     for (int i = 0; i < d->actionList.count(); ++i) {
    981         QAction *action = d->actionList.at(i);
     1027    for (int i = 0; i < d->actions.count(); ++i) {
     1028        QAction *action = d->actions.at(i);
    9821029        QRect adjustedActionRect = d->actionRect(action);
    9831030        if (adjustedActionRect.isEmpty() || !d->isVisible(action))
     
    10261073void QMenuBar::setVisible(bool visible)
    10271074{
    1028 #ifdef Q_WS_MAC
    1029     Q_D(QMenuBar);
    1030     if(d->mac_menubar)
    1031         return;
    1032 #endif
    1033 #ifdef Q_OS_WINCE
    1034     Q_D(QMenuBar);
    1035     if(d->wce_menubar)
     1075#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
     1076    if (isNativeMenuBar())
    10361077        return;
    10371078#endif
     
    10471088    if(e->button() != Qt::LeftButton)
    10481089        return;
     1090
     1091    d->mouseDown = true;
    10491092
    10501093    QAction *action = d->actionAt(e->pos());
     
    10571100        return;
    10581101    }
    1059 
    1060     d->mouseDown = true;
    10611102
    10621103    if(d->currentAction == action && d->popupState) {
     
    11011142{
    11021143    Q_D(QMenuBar);
     1144    d->updateGeometries();
    11031145    int key = e->key();
    11041146    if(isRightToLeft()) {  // in reverse mode open/close key for submenues are reversed
     
    11351177    case Qt::Key_Left: {
    11361178        if(d->currentAction) {
    1137             QAction *nextAction = 0;
    1138             bool allowActiveAndDisabled =
    1139                     style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this);
    1140 
    1141             for(int i=0; i<(int)d->actionList.count(); i++) {
    1142                 if(d->actionList.at(i) == (QAction*)d->currentAction) {
    1143                     if (key == Qt::Key_Left) {
    1144                         while (i > 0) {
    1145                             i--;
    1146                             if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) {
    1147                                 nextAction = d->actionList.at(i);
    1148                                 break;
    1149                             }
    1150                         }
    1151                     } else {
    1152                         while (i < d->actionList.count()-1) {
    1153                             i++;
    1154                             if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) {
    1155                                 nextAction = d->actionList.at(i);
    1156                                 break;
    1157                             }
    1158                         }
    1159                     }
    1160                     break;
    1161 
    1162                 }
    1163             }
    1164 
    1165             if(!nextAction) {
    1166                 if (key == Qt::Key_Left) {
    1167                     for (int i = d->actionList.size() - 1 ; i >= 0 ; --i) {
    1168                         if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) {
    1169                             nextAction = d->actionList.at(i);
    1170                             i--;
    1171                             break;
    1172                         }
    1173                     }
    1174                 } else {
    1175                     for (int i = 0 ; i < d->actionList.count() ; ++i) {
    1176                         if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) {
    1177                             nextAction = d->actionList.at(i);
    1178                             i++;
    1179                             break;
    1180                         }
    1181                     }
    1182                 }
    1183             }
    1184             if(nextAction) {
     1179            int index = d->actions.indexOf(d->currentAction);
     1180            if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) {
    11851181                d->setCurrentAction(nextAction, d->popupState, true);
    11861182                key_consumed = true;
     
    12061202        {
    12071203            QChar c = e->text()[0].toUpper();
    1208             for(int i = 0; i < d->actionList.size(); ++i) {
    1209                 register QAction *act = d->actionList.at(i);
     1204            for(int i = 0; i < d->actions.size(); ++i) {
     1205                if (d->actionRects.at(i).isNull())
     1206                    continue;
     1207                QAction *act = d->actions.at(i);
    12101208                QString s = act->text();
    12111209                if(!s.isEmpty()) {
     
    12491247{
    12501248    Q_D(QMenuBar);
    1251     d->mouseDown = e->buttons() & Qt::LeftButton;
     1249    if (!(e->buttons() & Qt::LeftButton))
     1250        d->mouseDown = false;
     1251    bool popupState = d->popupState || d->mouseDown;
    12521252    QAction *action = d->actionAt(e->pos());
    1253     bool popupState = d->popupState || d->mouseDown;
    12541253    if ((action && d->isVisible(action)) || !popupState)
    12551254        d->setCurrentAction(action, popupState);
     
    12621261{
    12631262    Q_D(QMenuBar);
    1264     if(!hasFocus() && !d->popupState)
     1263    if((!hasFocus() && !d->popupState) ||
     1264        (d->currentAction && d->currentAction->menu() == 0))
    12651265        d->setCurrentAction(0);
    12661266}
     
    12731273    Q_D(QMenuBar);
    12741274    d->itemsDirty = true;
     1275#if defined (Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
     1276    if (isNativeMenuBar()) {
    12751277#ifdef Q_WS_MAC
    1276     if(d->mac_menubar) {
     1278        QMenuBarPrivate::QMacMenuBarPrivate *nativeMenuBar = d->mac_menubar;
     1279#elif defined(Q_WS_S60)
     1280        QMenuBarPrivate::QSymbianMenuBarPrivate *nativeMenuBar = d->symbian_menubar;
     1281#else
     1282        QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar;
     1283#endif
     1284        if (!nativeMenuBar)
     1285            return;
    12771286        if(e->type() == QEvent::ActionAdded)
    1278             d->mac_menubar->addAction(e->action(), d->mac_menubar->findAction(e->before()));
     1287            nativeMenuBar->addAction(e->action(), nativeMenuBar->findAction(e->before()));
    12791288        else if(e->type() == QEvent::ActionRemoved)
    1280             d->mac_menubar->removeAction(e->action());
     1289            nativeMenuBar->removeAction(e->action());
    12811290        else if(e->type() == QEvent::ActionChanged)
    1282             d->mac_menubar->syncAction(e->action());
    1283     }
    1284 #endif
    1285 #ifdef Q_OS_WINCE
    1286     if(d->wce_menubar) {
    1287         if(e->type() == QEvent::ActionAdded)
    1288             d->wce_menubar->addAction(e->action(), d->wce_menubar->findAction(e->before()));
    1289         else if(e->type() == QEvent::ActionRemoved)
    1290             d->wce_menubar->removeAction(e->action());
    1291         else if(e->type() == QEvent::ActionChanged)
    1292             d->wce_menubar->syncAction(e->action());
    1293     }
    1294 #endif
     1291            nativeMenuBar->syncAction(e->action());
     1292    }
     1293#endif
     1294
    12951295    if(e->type() == QEvent::ActionAdded) {
    12961296        connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
     
    13111311{
    13121312    Q_D(QMenuBar);
    1313     if(d->keyboardState && !d->currentAction && !d->actionList.isEmpty())
    1314         d->setCurrentAction(d->actionList.first());
     1313    if(d->keyboardState)
     1314        d->focusFirstAction();
    13151315}
    13161316
     
    13711371
    13721372#ifdef Q_WS_MAC
    1373     macDestroyMenuBar();
    1374     macCreateMenuBar(newParent);
    1375 #endif
    1376 
    1377 #ifdef Q_OS_WINCE
     1373    if (q->isNativeMenuBar() && !macWidgetHasNativeMenubar(newParent)) {
     1374        // If the new parent got a native menubar from before, keep that
     1375        // menubar rather than replace it with this one (because a parents
     1376        // menubar has precedence over children menubars).
     1377        macDestroyMenuBar();
     1378        macCreateMenuBar(newParent);
     1379    }
     1380#endif
     1381
     1382#ifdef Q_WS_WINCE
    13781383    if (qt_wince_is_mobile() && wce_menubar)
    13791384        wce_menubar->rebuild();
    13801385#endif
     1386#ifdef Q_WS_S60
     1387    if (symbian_menubar)
     1388        symbian_menubar->rebuild();
     1389#endif
     1390
    13811391}
    13821392
     
    14801490    case QEvent::ShortcutOverride: {
    14811491        QKeyEvent *kev = static_cast<QKeyEvent*>(e);
    1482         if (kev->key() == Qt::Key_Escape) {
     1492        //we only filter out escape if there is a current action
     1493        if (kev->key() == Qt::Key_Escape && d->currentAction) {
    14831494            e->accept();
    14841495            return true;
     
    16131624{
    16141625    Q_D(const QMenuBar);
    1615 #ifdef Q_WS_MAC
    1616     const bool as_gui_menubar = !d->mac_menubar;
    1617 #elif defined (Q_OS_WINCE)
    1618     const bool as_gui_menubar = !d->wce_menubar;
     1626#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
     1627    const bool as_gui_menubar = !isNativeMenuBar();
    16191628#else
    16201629    const bool as_gui_menubar = true;
     
    16231632    ensurePolished();
    16241633    QSize ret(0, 0);
     1634    const_cast<QMenuBarPrivate*>(d)->updateGeometries();
    16251635    const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
    16261636    const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
     
    16281638    int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
    16291639    if(as_gui_menubar) {
    1630         QMap<QAction*, QRect> actionRects;
    1631         QList<QAction*> actionList;
    16321640        int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
    1633         d->calcActionRects(w - (2 * fw), 0, actionRects, actionList);
    1634         if (d->actionList.count() > 0) {
    1635             ret = d->actionRect(d->actionList.at(0)).size();
    1636             if (!d->extension->isHidden())
    1637                 ret += QSize(d->extension->sizeHint().width(), 0);
    1638         }
     1641        d->calcActionRects(w - (2 * fw), 0);
     1642        for (int i = 0; ret.isNull() && i < d->actions.count(); ++i)
     1643            ret = d->actionRects.at(i).size();
     1644        if (!d->extension->isHidden())
     1645            ret += QSize(d->extension->sizeHint().width(), 0);
    16391646        ret += QSize(2*fw + hmargin, 2*fw + vmargin);
    16401647    }
     
    16731680{
    16741681    Q_D(const QMenuBar);
    1675 #ifdef Q_WS_MAC
    1676     const bool as_gui_menubar = !d->mac_menubar;
    1677 #elif defined (Q_OS_WINCE)
    1678     const bool as_gui_menubar = !d->wce_menubar;
     1682#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
     1683    const bool as_gui_menubar = !isNativeMenuBar();
    16791684#else
    16801685    const bool as_gui_menubar = true;
    16811686#endif
    16821687
     1688
    16831689    ensurePolished();
    16841690    QSize ret(0, 0);
     1691    const_cast<QMenuBarPrivate*>(d)->updateGeometries();
    16851692    const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
    16861693    const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
     
    16881695    int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
    16891696    if(as_gui_menubar) {
    1690         QMap<QAction*, QRect> actionRects;
    1691         QList<QAction*> actionList;
    16921697        const int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
    1693         d->calcActionRects(w - (2 * fw), 0, actionRects, actionList);
    1694         for (QMap<QAction*, QRect>::const_iterator i = actionRects.constBegin();
    1695              i != actionRects.constEnd(); ++i) {
    1696             QRect actionRect(i.value());
    1697             if(actionRect.x() + actionRect.width() > ret.width())
    1698                 ret.setWidth(actionRect.x() + actionRect.width());
    1699             if(actionRect.y() + actionRect.height() > ret.height())
    1700                 ret.setHeight(actionRect.y() + actionRect.height());
    1701         }
    1702         ret += QSize(2*fw + 2*hmargin, 2*fw + 2*vmargin);
     1698        d->calcActionRects(w - (2 * fw), 0);
     1699        for (int i = 0; i < d->actionRects.count(); ++i) {
     1700            const QRect &actionRect = d->actionRects.at(i);
     1701            ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height()));
     1702        }
     1703        //the action geometries already contain the top and left
     1704        //margins. So we only need to add those from right and bottom.
     1705        ret += QSize(fw + hmargin, fw + vmargin);
    17031706    }
    17041707    int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
     
    17361739{
    17371740    Q_D(const QMenuBar);
    1738 #ifdef Q_WS_MAC
    1739     const bool as_gui_menubar = !d->mac_menubar;
    1740 #elif defined (Q_OS_WINCE)
    1741     const bool as_gui_menubar = !d->wce_menubar;
     1741#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
     1742    const bool as_gui_menubar = !isNativeMenuBar();
    17421743#else
    17431744    const bool as_gui_menubar = true;
    17441745#endif
     1746
     1747    const_cast<QMenuBarPrivate*>(d)->updateGeometries();
    17451748    int height = 0;
    17461749    const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
     
    17481751    int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
    17491752    if(as_gui_menubar) {
    1750         if (d->actionList.count()) {
    1751             // assume all actionrects have the same height
    1752             height = d->actionRect(d->actionList.first()).height();
     1753        for (int i = 0; i < d->actionRects.count(); ++i)
     1754            height = qMax(height, d->actionRects.at(i).height());
     1755        if (height) //there is at least one non-null item
    17531756            height += spaceBelowMenuBar;
    1754         }
    17551757        height += 2*fw;
    17561758        height += 2*vmargin;
     
    17791781{
    17801782    Q_Q(QMenuBar);
    1781     QAction *act = actionList.at(id);
     1783    QAction *act = actions.at(id);
    17821784    setCurrentAction(act, true, true);
    17831785    if (act && !act->menu()) {
     
    17851787        //100 is the same as the default value in QPushButton::animateClick
    17861788        autoReleaseTimer.start(100, q);
     1789    } else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {
     1790        // When we open a menu using a shortcut, we should end up in keyboard state
     1791        setKeyboardMode(true);
    17871792    }
    17881793}
     
    18571862
    18581863/*!
     1864    \property QMenuBar::nativeMenuBar
     1865    \brief Whether or not a menubar will be used as a native menubar on platforms that support it
     1866    \since 4.6
     1867
     1868    This property specifies whether or not the menubar should be used as a native menubar on platforms
     1869    that support it. The currently supported platforms are Mac OS X and Windows CE. On these platforms
     1870    if this property is true, the menubar is used in the native menubar and is not in the window of
     1871    its parent, if false the menubar remains in the window. On other platforms the value of this
     1872    attribute has no effect.
     1873
     1874    The default is to follow whether the Qt::AA_DontUseNativeMenuBar attribute
     1875    is set for the application. Explicitly settings this property overrides
     1876    the presence (or abscence) of the attribute.
     1877*/
     1878
     1879void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
     1880{
     1881    Q_D(QMenuBar);
     1882    if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) {
     1883        d->nativeMenuBar = nativeMenuBar;
     1884#ifdef Q_WS_MAC
     1885        if (!d->nativeMenuBar) {
     1886            extern void qt_mac_clear_menubar();
     1887            qt_mac_clear_menubar();
     1888            d->macDestroyMenuBar();
     1889            const QList<QAction *> &menubarActions = actions();
     1890            for (int i = 0; i < menubarActions.size(); ++i) {
     1891                const QAction *action = menubarActions.at(i);
     1892                if (QMenu *menu = action->menu()) {
     1893                    delete menu->d_func()->mac_menu;
     1894                    menu->d_func()->mac_menu = 0;
     1895                }
     1896            }
     1897        } else {
     1898            d->macCreateMenuBar(parentWidget());
     1899        }
     1900        macUpdateMenuBar();
     1901        updateGeometry();
     1902        setVisible(false);
     1903        setVisible(true);
     1904#endif
     1905    }
     1906}
     1907
     1908bool QMenuBar::isNativeMenuBar() const
     1909{
     1910    Q_D(const QMenuBar);
     1911    if (d->nativeMenuBar == -1) {
     1912        return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar);
     1913    }
     1914    return d->nativeMenuBar;
     1915}
     1916
     1917/*!
    18591918  \since 4.4
    18601919
     
    18701929*/
    18711930
    1872 #ifdef Q_OS_WINCE
     1931#ifdef Q_WS_WINCE
    18731932void QMenuBar::setDefaultAction(QAction *act)
    18741933{
     
    18761935    if (d->defaultAction == act)
    18771936        return;
    1878 #ifdef Q_OS_WINCE
     1937#ifdef Q_WS_WINCE
    18791938    if (qt_wince_is_mobile())
    18801939        if (d->defaultAction) {
    18811940            disconnect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction()));
    1882             disconnect(d->defaultAction, SIGNAL(destroyed ()), this, SLOT(_q_updateDefaultAction()));
     1941            disconnect(d->defaultAction, SIGNAL(destroyed()), this, SLOT(_q_updateDefaultAction()));
    18831942        }
    18841943#endif
    18851944    d->defaultAction = act;
    1886 #ifdef Q_OS_WINCE
     1945#ifdef Q_WS_WINCE
    18871946    if (qt_wince_is_mobile())
    18881947        if (d->defaultAction) {
     
    23802439/*!
    23812440    \fn int QMenuBar::margin() const
    2382     Returns the with of the the margin around the contents of the widget.
     2441    Returns the width of the margin around the contents of the widget.
    23832442
    23842443    Use QWidget::getContentsMargins() instead.
Note: See TracChangeset for help on using the changeset viewer.