diff options
author | Ariya Hidayat <ariya.hidayat@nokia.com> | 2009-06-30 10:55:05 (GMT) |
---|---|---|
committer | Ariya Hidayat <ariya.hidayat@nokia.com> | 2009-06-30 10:55:05 (GMT) |
commit | 5a3db7268eb9203e91fc09e5db6d8690274464d7 (patch) | |
tree | 8741a59911d56325b69360632c64a29be6370b39 /src/gui | |
parent | 5b52ab8161d7731c7728d176b13a4a28480bc1db (diff) | |
parent | 5a54b2c4c448ea22adb56bc191303abca34f230b (diff) | |
download | Qt-5a3db7268eb9203e91fc09e5db6d8690274464d7.zip Qt-5a3db7268eb9203e91fc09e5db6d8690274464d7.tar.gz Qt-5a3db7268eb9203e91fc09e5db6d8690274464d7.tar.bz2 |
Merge commit 'master/master' into kinetic-graphicseffect
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qdirectionrecognizer.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qevent.cpp | 33 | ||||
-rw-r--r-- | src/gui/kernel/qlayout.cpp | 5 | ||||
-rw-r--r-- | src/gui/styles/qstyleoption.cpp | 3 | ||||
-rw-r--r-- | src/gui/widgets/qdockarealayout.cpp | 4 | ||||
-rw-r--r-- | src/gui/widgets/qdockwidget.cpp | 3 | ||||
-rw-r--r-- | src/gui/widgets/qmenu.cpp | 30 | ||||
-rw-r--r-- | src/gui/widgets/qmenu_p.h | 4 | ||||
-rw-r--r-- | src/gui/widgets/qmenubar.cpp | 239 | ||||
-rw-r--r-- | src/gui/widgets/qmenubar_p.h | 16 | ||||
-rw-r--r-- | src/gui/widgets/widgets.pri | 2 |
11 files changed, 178 insertions, 165 deletions
diff --git a/src/gui/kernel/qdirectionrecognizer.cpp b/src/gui/kernel/qdirectionrecognizer.cpp index b88d4f0..a1bc5b1 100644 --- a/src/gui/kernel/qdirectionrecognizer.cpp +++ b/src/gui/kernel/qdirectionrecognizer.cpp @@ -43,6 +43,10 @@ #include <math.h> +#ifndef M_PI +#define M_PI 3.141592653589793238462643 +#endif + QT_BEGIN_NAMESPACE enum { diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 2467a62..e40ad9d 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3647,12 +3647,13 @@ void QGestureEvent::acceptAll() } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} + Sets the accept flag of the gesture specified by \a type. + This is equivalent to calling + \l{QGestureEvent::gesture()}{gesture(type)}-> + \l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent + Setting the accept flag indicates that the event receiver wants + the gesture. Unwanted gestures might be propagated to the parent widget. */ void QGestureEvent::accept(Qt::GestureType type) @@ -3662,12 +3663,13 @@ void QGestureEvent::accept(Qt::GestureType type) } /*! - Sets the accept flag of the specified gesture inside the event - object, the equivalent of calling - \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()} + Sets the accept flag of the gesture specified by \a type. + This is equivalent to calling + \l{QGestureEvent::gesture()}{gesture(type)}-> + \l{QGesture::accept()}{accept()} - Setting the accept parameter indicates that the event receiver - wants the gesture. Unwanted gestures might be propagated to the parent + Setting the accept flag indicates that the event receiver wants + the gesture. Unwanted gestures might be propagated to the parent widget. */ void QGestureEvent::accept(const QString &type) @@ -4165,4 +4167,15 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T return *this; } +/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const + Returns the touch device Type, which is of type + \l {QTouchEvent::DeviceType} {DeviceType}. + */ + +/*! \fn void QTouchEvent::setDeviceType(DeviceType deviceType) + Sets the device type to \a deviceType, which is of type + \l {QTouchEvent::DeviceType} {DeviceType}. + */ + + QT_END_NAMESPACE diff --git a/src/gui/kernel/qlayout.cpp b/src/gui/kernel/qlayout.cpp index 3a3feb2..e750088 100644 --- a/src/gui/kernel/qlayout.cpp +++ b/src/gui/kernel/qlayout.cpp @@ -61,7 +61,10 @@ static int menuBarHeightForWidth(QWidget *menubar, int w) int result = menubar->heightForWidth(qMax(w, menubar->minimumWidth())); if (result != -1) return result; - result = menubar->sizeHint().height(); + result = menubar->sizeHint() + .expandedTo(menubar->minimumSize()) + .expandedTo(menubar->minimumSizeHint()) + .boundedTo(menubar->maximumSize()).height(); if (result != -1) return result; } diff --git a/src/gui/styles/qstyleoption.cpp b/src/gui/styles/qstyleoption.cpp index 704f8ba..e174370 100644 --- a/src/gui/styles/qstyleoption.cpp +++ b/src/gui/styles/qstyleoption.cpp @@ -3542,7 +3542,8 @@ QStyleOptionQ3DockWindow::QStyleOptionQ3DockWindow(int version) */ QStyleOptionDockWidget::QStyleOptionDockWidget() - : QStyleOption(Version, SO_DockWidget), movable(false) + : QStyleOption(Version, SO_DockWidget), closable(false), + movable(false), floatable(false) { } diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index ea5e323..9828413 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -223,7 +223,7 @@ static quintptr tabId(const QDockAreaLayoutItem &item) QDockAreaLayoutInfo::QDockAreaLayoutInfo() : sep(0), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0) #ifndef QT_NO_TABBAR - , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth) + , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth), tabBarVisible(false) #endif { } @@ -233,7 +233,7 @@ QDockAreaLayoutInfo::QDockAreaLayoutInfo(int _sep, QInternal::DockPosition _dock QMainWindow *window) : sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window) #ifndef QT_NO_TABBAR - , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape)) + , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape)), tabBarVisible(false) #endif { #ifdef QT_NO_TABBAR diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index 4350520..5810c81 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -1322,8 +1322,7 @@ void QDockWidget::changeEvent(QEvent *event) QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget()); if (QMainWindowLayout *winLayout = (win ? qobject_cast<QMainWindowLayout*>(win->layout()) : 0)) - if (QDockAreaLayoutInfo *info = - (winLayout ? winLayout->layoutState.dockAreaLayout.info(this) : 0)) + if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this)) info->updateTabBar(); } #endif // QT_NO_TABBAR diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 2f20991..d3f5bc5 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -150,7 +150,6 @@ private: void QMenuPrivate::init() { Q_Q(QMenu); - activationRecursionGuard = false; #ifndef QT_NO_WHATSTHIS q->setAttribute(Qt::WA_CustomWhatsThis); #endif @@ -484,9 +483,9 @@ void QMenuPrivate::setSyncAction() void QMenuPrivate::setFirstActionActive() { Q_Q(QMenu); + updateActionRects(); const int scrollerHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); for(int i = 0, saccum = 0; i < actions.count(); i++) { - QAction *act = actions.at(i); const QRect &rect = actionRects.at(i); if (rect.isNull()) continue; @@ -495,6 +494,7 @@ void QMenuPrivate::setFirstActionActive() if (saccum > scroll->scrollOffset-scrollerHeight) continue; } + QAction *act = actions.at(i); if (!act->isSeparator() && (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q) || act->isEnabled())) { @@ -667,6 +667,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc Q_Q(QMenu); if (!scroll || !scroll->scrollFlags) return; + updateActionRects(); int newOffset = 0; const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; @@ -769,6 +770,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc void QMenuPrivate::scrollMenu(QMenuScroller::ScrollLocation location, bool active) { Q_Q(QMenu); + updateActionRects(); if(location == QMenuScroller::ScrollBottom) { for(int i = actions.size()-1; i >= 0; --i) { QAction *act = actions.at(i); @@ -808,6 +810,7 @@ void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool pag Q_Q(QMenu); if (!scroll || !(scroll->scrollFlags & direction)) //not really possible... return; + updateActionRects(); const int scrollHeight = q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q); const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollHeight : 0; const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollHeight : 0; @@ -1704,24 +1707,25 @@ QSize QMenu::sizeHint() const const QRect &rect = d->actionRects.at(i); if (rect.isNull()) continue; - if (rect.bottom() > s.height()) - s.setHeight(rect.y()+rect.height()); - if (rect.right() > s.width()) - s.setWidth(rect.right()); + if (rect.bottom() >= s.height()) + s.setHeight(rect.y() + rect.height()); + if (rect.right() >= s.width()) + s.setWidth(rect.x() + rect.width()); } if (d->tearoff) s.rheight() += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, this); - if (const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this)) { - s.rwidth() += fw*2; - s.rheight() += fw*2; - } // Note that the action rects calculated above already include // the top and left margins, so we only need to add margins for // the bottom and right. + if (const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this)) { + s.rwidth() += fw; + s.rheight() += fw; + } + s.rwidth() += style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this); s.rheight() += style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, this); - s += QSize(d->leftmargin + d->rightmargin, d->topmargin + d->bottommargin); + s += QSize(d->rightmargin, d->bottommargin); return style()->sizeFromContents(QStyle::CT_Menu, &opt, s.expandedTo(QApplication::globalStrut()), this); @@ -2058,6 +2062,7 @@ void QMenu::hideEvent(QHideEvent *) void QMenu::paintEvent(QPaintEvent *e) { Q_D(QMenu); + d->updateActionRects(); QPainter p(this); QRegion emptyArea = QRegion(rect()); @@ -2344,6 +2349,7 @@ bool QMenu::focusNextPrevChild(bool next) void QMenu::keyPressEvent(QKeyEvent *e) { Q_D(QMenu); + d->updateActionRects(); int key = e->key(); if (isRightToLeft()) { // in reverse mode open/close key for submenues are reversed if (key == Qt::Key_Left) @@ -2711,7 +2717,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e) d->motions++; if (d->motions == 0) // ignore first mouse move event (see enterEvent()) return; - d->hasHadMouse |= rect().contains(e->pos()); + d->hasHadMouse = d->hasHadMouse || rect().contains(e->pos()); QAction *action = d->actionAt(e->pos()); if (!action) { diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 7bc78ba..50a9f2f 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -126,9 +126,9 @@ class QMenuPrivate : public QWidgetPrivate Q_DECLARE_PUBLIC(QMenu) public: QMenuPrivate() : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0), - collapsibleSeparators(true), hasHadMouse(0), aboutToHide(0), motions(0), + collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0), currentAction(0), scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0), - hasCheckableItems(0), sloppyAction(0) + hasCheckableItems(0), sloppyAction(0), doChildEffects(false) #ifdef Q_WS_MAC ,mac_menu(0) #endif diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 34de252..f4288ac 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -197,17 +197,15 @@ void QMenuBarPrivate::updateGeometries() return; } #endif - calcActionRects(q_width, q_start, actionRects, actionList); - itemsWidth = q_width; - itemsStart = q_start; + calcActionRects(q_width, q_start); currentAction = 0; #ifndef QT_NO_SHORTCUT if(itemsDirty) { for(int j = 0; j < shortcutIndexMap.size(); ++j) q->releaseShortcut(shortcutIndexMap.value(j)); shortcutIndexMap.resize(0); // faster than clear - for(int i = 0; i < actionList.count(); i++) - shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actionList.at(i)->text()))); + for(int i = 0; i < actions.count(); i++) + shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text()))); } #endif itemsDirty = false; @@ -218,9 +216,9 @@ void QMenuBarPrivate::updateGeometries() //we try to see if the actions will fit there bool hasHiddenActions = false; - for (int i = 0; i < actionList.count(); ++i) { - QAction *action = actionList.at(i); - if (!menuRect.contains(actionRect(action))) { + for (int i = 0; i < actions.count(); ++i) { + const QRect &rect = actionRects.at(i); + if (!menuRect.contains(rect)) { hasHiddenActions = true; break; } @@ -229,10 +227,10 @@ void QMenuBarPrivate::updateGeometries() //...and if not, determine the ones that fit on the menu with the extension visible if (hasHiddenActions) { menuRect = this->menuRect(true); - for (int i = 0; i < actionList.count(); ++i) { - QAction *action = actionList.at(i); - if (!menuRect.contains(actionRect(action))) { - hiddenActions.append(action); + for (int i = 0; i < actions.count(); ++i) { + const QRect &rect = actionRects.at(i); + if (!menuRect.contains(rect)) { + hiddenActions.append(actions.at(i)); } } } @@ -267,12 +265,28 @@ void QMenuBarPrivate::updateGeometries() QRect QMenuBarPrivate::actionRect(QAction *act) const { Q_Q(const QMenuBar); - QRect ret = actionRects.value(act); - const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); - ret.translate(fw, fw); + const int index = actions.indexOf(act); + if (index == -1) + return QRect(); + + //makes sure the geometries are up-to-date + const_cast<QMenuBarPrivate*>(this)->updateGeometries(); + + QRect ret = actionRects.at(index); return QStyle::visualRect(q->layoutDirection(), q->rect(), ret); } +void QMenuBarPrivate::focusFirstAction() +{ + if(!currentAction) { + updateGeometries(); + int index = 0; + while (index < actions.count() && actionRects.at(index).isNull()) ++index; + if (index < actions.count()) + setCurrentAction(actions.at(index)); + } +} + void QMenuBarPrivate::setKeyboardMode(bool b) { Q_Q(QMenuBar); @@ -285,8 +299,7 @@ void QMenuBarPrivate::setKeyboardMode(bool b) QWidget *fw = QApplication::focusWidget(); if (fw != q) keyboardFocusWidget = fw; - if(!currentAction && !actionList.isEmpty()) - setCurrentAction(actionList.first()); + focusFirstAction(); q->setFocus(Qt::MenuBarFocusReason); } else { if(!popupState) @@ -398,25 +411,27 @@ void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activat fw->setFocus(Qt::NoFocusReason); } -void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const +void QMenuBarPrivate::calcActionRects(int max_width, int start) const { Q_Q(const QMenuBar); - if(!itemsDirty && itemsWidth == max_width && itemsStart == start) { - actionRects = actionRects; - actionList = actionList; + if(!itemsDirty) return; - } - actionRects.clear(); - actionList.clear(); - const int itemSpacing = q->style()->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q); + + //let's reinitialize the buffer + actionRects.resize(actions.count()); + actionRects.fill(QRect()); + + const QStyle *style = q->style(); + + const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q); int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0; //calculate size const QFontMetrics fm = q->fontMetrics(); - const int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q), - vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q), - icone = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q); + const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q), + vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q), + icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q); for(int i = 0; i < actions.count(); i++) { QAction *action = actions.at(i); if(!action->isVisible()) @@ -426,26 +441,21 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, Q //calc what I think the size is.. if(action->isSeparator()) { - if (q->style()->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q)) - separator = actionRects.count(); + if (style->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q)) + separator = i; continue; //we don't really position these! } else { - QString s = action->text(); + const QString s = action->text(); if(!s.isEmpty()) { - int w = fm.width(s); - w -= s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&')); - w += s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&')); + const int w = fm.width(s) + - s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&')) + + s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&')); sz = QSize(w, fm.height()); } QIcon is = action->icon(); - if (!is.isNull()) { - QSize is_sz = QSize(icone, icone); - if (is_sz.height() > sz.height()) - sz.setHeight(is_sz.height()); - if (is_sz.width() > sz.width()) - sz.setWidth(is_sz.width()); - } + if (!is.isNull()) + sz = sz.expandedTo(QSize(icone, icone)); } //let the style modify the above size.. @@ -455,8 +465,7 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, Q if(!sz.isEmpty()) { { //update the separator state - int iWidth = sz.width(); - iWidth += itemSpacing; + int iWidth = sz.width() + itemSpacing; if(separator == -1) separator_start += iWidth; else @@ -465,17 +474,19 @@ void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, Q //maximum height max_item_height = qMax(max_item_height, sz.height()); //append - actionRects.insert(action, QRect(0, 0, sz.width(), sz.height())); - actionList.append(action); + actionRects[i] = QRect(0, 0, sz.width(), sz.height()); } } //calculate position - int x = ((start == -1) ? hmargin : start) + itemSpacing; - int y = vmargin; - for(int i = 0; i < actionList.count(); i++) { - QAction *action = actionList.at(i); - QRect &rect = actionRects[action]; + const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q); + int x = fw + ((start == -1) ? hmargin : start) + itemSpacing; + int y = fw + vmargin; + for(int i = 0; i < actions.count(); i++) { + QRect &rect = actionRects[i]; + if (rect.isNull()) + continue; + //resize rect.setHeight(max_item_height); @@ -743,6 +754,28 @@ void QMenuBarPrivate::init() extension->hide(); } +//Gets the next action for keyboard navigation +QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const +{ + Q_Q(const QMenuBar); + const_cast<QMenuBarPrivate*>(this)->updateGeometries(); + bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q); + const int start = (_start == -1 && increment == -1) ? actions.count() : _start; + const int end = increment == -1 ? 0 : actions.count() - 1; + + for (int i = start; start != end;) { + i += increment; + QAction *current = actions.at(i); + if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled())) + return current; + } + + if (_start != -1) //let's try from the beginning or the end + return getNextAction(-1, increment); + + return 0; +} + /*! Constructs a menu bar with parent \a parent. */ @@ -975,8 +1008,8 @@ void QMenuBar::paintEvent(QPaintEvent *e) QRegion emptyArea(rect()); //draw the items - for (int i = 0; i < d->actionList.count(); ++i) { - QAction *action = d->actionList.at(i); + for (int i = 0; i < d->actions.count(); ++i) { + QAction *action = d->actions.at(i); QRect adjustedActionRect = d->actionRect(action); if (adjustedActionRect.isEmpty() || !d->isVisible(action)) continue; @@ -1092,6 +1125,7 @@ void QMenuBar::mouseReleaseEvent(QMouseEvent *e) void QMenuBar::keyPressEvent(QKeyEvent *e) { Q_D(QMenuBar); + d->updateGeometries(); int key = e->key(); if(isRightToLeft()) { // in reverse mode open/close key for submenues are reversed if(key == Qt::Key_Left) @@ -1126,54 +1160,8 @@ void QMenuBar::keyPressEvent(QKeyEvent *e) case Qt::Key_Right: case Qt::Key_Left: { if(d->currentAction) { - QAction *nextAction = 0; - bool allowActiveAndDisabled = - style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this); - - for(int i=0; i<(int)d->actionList.count(); i++) { - if(d->actionList.at(i) == (QAction*)d->currentAction) { - if (key == Qt::Key_Left) { - while (i > 0) { - i--; - if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) { - nextAction = d->actionList.at(i); - break; - } - } - } else { - while (i < d->actionList.count()-1) { - i++; - if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) { - nextAction = d->actionList.at(i); - break; - } - } - } - break; - - } - } - - if(!nextAction) { - if (key == Qt::Key_Left) { - for (int i = d->actionList.size() - 1 ; i >= 0 ; --i) { - if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) { - nextAction = d->actionList.at(i); - i--; - break; - } - } - } else { - for (int i = 0 ; i < d->actionList.count() ; ++i) { - if (allowActiveAndDisabled || d->actionList[i]->isEnabled()) { - nextAction = d->actionList.at(i); - i++; - break; - } - } - } - } - if(nextAction) { + int index = d->actions.indexOf(d->currentAction); + if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) { d->setCurrentAction(nextAction, d->popupState, true); key_consumed = true; } @@ -1197,8 +1185,10 @@ void QMenuBar::keyPressEvent(QKeyEvent *e) QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0; { QChar c = e->text()[0].toUpper(); - for(int i = 0; i < d->actionList.size(); ++i) { - register QAction *act = d->actionList.at(i); + for(int i = 0; i < d->actions.size(); ++i) { + if (d->actionRects.at(i).isNull()) + continue; + QAction *act = d->actions.at(i); QString s = act->text(); if(!s.isEmpty()) { int ampersand = s.indexOf(QLatin1Char('&')); @@ -1300,8 +1290,8 @@ void QMenuBar::actionEvent(QActionEvent *e) void QMenuBar::focusInEvent(QFocusEvent *) { Q_D(QMenuBar); - if(d->keyboardState && !d->currentAction && !d->actionList.isEmpty()) - d->setCurrentAction(d->actionList.first()); + if(d->keyboardState) + d->focusFirstAction(); } /*! @@ -1610,20 +1600,18 @@ QSize QMenuBar::minimumSizeHint() const ensurePolished(); QSize ret(0, 0); + const_cast<QMenuBarPrivate*>(d)->updateGeometries(); const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this); const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this); int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); if(as_gui_menubar) { - QMap<QAction*, QRect> actionRects; - QList<QAction*> actionList; int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width(); - d->calcActionRects(w - (2 * fw), 0, actionRects, actionList); - if (d->actionList.count() > 0) { - ret = d->actionRect(d->actionList.at(0)).size(); - if (!d->extension->isHidden()) - ret += QSize(d->extension->sizeHint().width(), 0); - } + d->calcActionRects(w - (2 * fw), 0); + for (int i = 0; ret.isNull() && i < d->actions.count(); ++i) + ret = d->actionRects.at(i).size(); + if (!d->extension->isHidden()) + ret += QSize(d->extension->sizeHint().width(), 0); ret += QSize(2*fw + hmargin, 2*fw + vmargin); } int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; @@ -1674,19 +1662,15 @@ QSize QMenuBar::sizeHint() const int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); if(as_gui_menubar) { - QMap<QAction*, QRect> actionRects; - QList<QAction*> actionList; const int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width(); - d->calcActionRects(w - (2 * fw), 0, actionRects, actionList); - for (QMap<QAction*, QRect>::const_iterator i = actionRects.constBegin(); - i != actionRects.constEnd(); ++i) { - QRect actionRect(i.value()); - if(actionRect.x() + actionRect.width() > ret.width()) - ret.setWidth(actionRect.x() + actionRect.width()); - if(actionRect.y() + actionRect.height() > ret.height()) - ret.setHeight(actionRect.y() + actionRect.height()); + d->calcActionRects(w - (2 * fw), 0); + for (int i = 0; i < d->actionRects.count(); ++i) { + const QRect &actionRect = d->actionRects.at(i); + ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height())); } - ret += QSize(2*fw + 2*hmargin, 2*fw + 2*vmargin); + //the action geometries already contain the top and left + //margins. So we only need to add those from right and bottom. + ret += QSize(fw + hmargin, fw + vmargin); } int margin = 2*vmargin + 2*fw + spaceBelowMenuBar; if(d->leftWidget) { @@ -1733,11 +1717,10 @@ int QMenuBar::heightForWidth(int) const int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this); int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this); if(as_gui_menubar) { - if (d->actionList.count()) { - // assume all actionrects have the same height - height = d->actionRect(d->actionList.first()).height(); + for (int i = 0; i < d->actionRects.count(); ++i) + height = qMax(height, d->actionRects.at(i).height()); + if (height) //there is at least one non-null item height += spaceBelowMenuBar; - } height += 2*fw; height += 2*vmargin; } @@ -1764,7 +1747,7 @@ int QMenuBar::heightForWidth(int) const void QMenuBarPrivate::_q_internalShortcutActivated(int id) { Q_Q(QMenuBar); - QAction *act = actionList.at(id); + QAction *act = actions.at(id); setCurrentAction(act, true, true); if (act && !act->menu()) { activateAction(act, QAction::Trigger); diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h index 0a4fbfe..b890b7b 100644 --- a/src/gui/widgets/qmenubar_p.h +++ b/src/gui/widgets/qmenubar_p.h @@ -69,9 +69,12 @@ class QMenuBarPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QMenuBar) public: - QMenuBarPrivate() : itemsDirty(0), itemsWidth(0), itemsStart(-1), currentAction(0), mouseDown(0), + QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0), closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0), - nativeMenuBar(-1) + nativeMenuBar(-1), doChildEffects(false) +#ifdef QT3_SUPPORT + , doAutoResize(false) +#endif #ifdef Q_WS_MAC , mac_menubar(0) #endif @@ -91,16 +94,14 @@ public: } void init(); - QStyleOptionMenuItem getStyleOption(const QAction *action) const; + QAction *getNextAction(const int start, const int increment) const; //item calculations uint itemsDirty : 1; - int itemsWidth, itemsStart; QVector<int> shortcutIndexMap; - mutable QMap<QAction*, QRect> actionRects; - mutable QList<QAction*> actionList; - void calcActionRects(int max_width, int start, QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const; + mutable QVector<QRect> actionRects; + void calcActionRects(int max_width, int start) const; QRect actionRect(QAction *) const; void updateGeometries(); @@ -116,6 +117,7 @@ public: QPointer<QMenu> activeMenu; //keyboard mode for keyboard navigation + void focusFirstAction(); void setKeyboardMode(bool); uint keyboardState : 1, altPressed : 1; QPointer<QWidget> keyboardFocusWidget; diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri index 86dc453..2d809a1 100644 --- a/src/gui/widgets/widgets.pri +++ b/src/gui/widgets/widgets.pri @@ -37,7 +37,9 @@ HEADERS += \ widgets/qmdisubwindow.h \ widgets/qmdisubwindow_p.h \ widgets/qmenu.h \ + widgets/qmenu_p.h \ widgets/qmenubar.h \ + widgets/qmenubar_p.h \ widgets/qmenudata.h \ widgets/qprogressbar.h \ widgets/qpushbutton.h \ |