diff options
author | Thierry Bastian <thierry.bastian@nokia.com> | 2009-06-26 13:13:08 (GMT) |
---|---|---|
committer | Thierry Bastian <thierry.bastian@nokia.com> | 2009-06-26 13:48:51 (GMT) |
commit | 4b6ab00e6d68c7f7d25df329c1b530c4b5fc2abf (patch) | |
tree | 289171bebe4e5f1c2c864a70adfd2d0673a4a668 | |
parent | 9e6a2c4cf8f0e151d7171dd63527d3de8ae33a4e (diff) | |
download | Qt-4b6ab00e6d68c7f7d25df329c1b530c4b5fc2abf.zip Qt-4b6ab00e6d68c7f7d25df329c1b530c4b5fc2abf.tar.gz Qt-4b6ab00e6d68c7f7d25df329c1b530c4b5fc2abf.tar.bz2 |
QMenu: refactor for the QWidgetActions' widget.
We now use QList/QVector over QHash. It is more efficient because most
of the time we iterate over the list of actions anyway.
-rw-r--r-- | src/gui/widgets/qmenu.cpp | 52 | ||||
-rw-r--r-- | src/gui/widgets/qmenu_p.h | 2 |
2 files changed, 24 insertions, 30 deletions
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 0983c37..2f20991 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -233,7 +233,7 @@ void QMenuPrivate::updateActionRects() const for (int i = 0; i < actions.count(); ++i) { QAction *action = actions.at(i); - if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action)) + if (action->isSeparator() || !action->isVisible() || widgetItems.at(i)) continue; //..and some members hasCheckableItems |= action->isCheckable(); @@ -262,7 +262,7 @@ void QMenuPrivate::updateActionRects() const const QFontMetrics &fm = opt.fontMetrics; QSize sz; - if (QWidget *w = widgetItems.value(action)) { + if (QWidget *w = widgetItems.at(i)) { sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize()); } else { //calc what I think the size is.. @@ -335,10 +335,9 @@ void QMenuPrivate::updateActionRects() const rect.setWidth(max_column_width); //uniform width //we need to update the widgets geometry - QAction *action = actions.at(i); - if (QWidget *widget = widgetItems.value(action)) { + if (QWidget *widget = widgetItems.at(i)) { widget->setGeometry(rect); - widget->setVisible(action->isVisible()); + widget->setVisible(actions.at(i)->isVisible()); } y += rect.height(); @@ -545,9 +544,10 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason popupAction(currentAction, popup, activateFirst); } q->update(actionRect(action)); - QWidget *widget = widgetItems.value(action); if (reason == SelectedFromKeyboard) { + const int actionIndex = actions.indexOf(action); + QWidget *widget = widgetItems.at(actionIndex); if (widget) { if (widget->focusPolicy() != Qt::NoFocus) widget->setFocus(Qt::TabFocusReason); @@ -1335,14 +1335,13 @@ QMenu::QMenu(QMenuPrivate &dd, QWidget *parent) QMenu::~QMenu() { Q_D(QMenu); - for (QHash<QAction *, QWidget *>::ConstIterator item = d->widgetItems.constBegin(), - end = d->widgetItems.constEnd(); item != end; ++item) { - QWidgetAction *action = static_cast<QWidgetAction *>(item.key()); - QWidget *widget = item.value(); - if (action && widget) + for (int i = 0; i < d->widgetItems.count(); ++i) { + if (QWidget *widget = d->widgetItems.at(i)) { + QWidgetAction *action = static_cast<QWidgetAction *>(d->actions.at(i)); action->releaseWidget(widget); + d->widgetItems[i] = 0; + } } - d->widgetItems.clear(); if (d->eventLoop) d->eventLoop->exit(); @@ -2075,7 +2074,7 @@ void QMenu::paintEvent(QPaintEvent *e) QAction *action = d->actions.at(i); QRect adjustedActionRect = d->actionRects.at(i); if (!e->rect().intersects(adjustedActionRect) - || d->widgetItems.value(action)) + || d->widgetItems.at(i)) continue; //set the clip region to be extra safe (and adjust for the scrollers) QRegion adjustedActionReg(adjustedActionRect); @@ -2786,30 +2785,25 @@ void QMenu::actionEvent(QActionEvent *e) connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered())); connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered())); } + QWidget *widget = 0; + if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) + widget = wa->requestWidget(this); + + int index = d->actions.indexOf(e->action()); + Q_ASSERT(index != -1); + d->widgetItems.insert(index, widget); - if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) { - QWidget *widget = wa->requestWidget(this); - if (widget) - d->widgetItems.insert(wa, widget); - } } else if (e->type() == QEvent::ActionRemoved) { - d->actionRects.clear(); e->action()->disconnect(this); if (e->action() == d->currentAction) d->currentAction = 0; + int index = d->actions.indexOf(e->before()) + 1; if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) { - QWidget *widget = d->widgetItems.take(wa); - if (widget) + if (QWidget *widget = d->widgetItems.at(index)) wa->releaseWidget(widget); - } else { - // If this is called from the QAction destructor, the - // previous call to qobject_cast will fail because the - // QWidgetAction has been destroyed already. We need to - // remove it from the hash anyway or it might crash later - // the widget itself has been already destroyed in - // ~QWidgetAction - d->widgetItems.remove(e->action()); } + Q_ASSERT(index != -1); + d->widgetItems.removeAt(index); } #ifdef Q_WS_MAC diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index cd750d5..7bc78ba 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -157,7 +157,7 @@ public: QRect actionRect(QAction *) const; mutable QVector<QRect> actionRects; - mutable QHash<QAction *, QWidget *> widgetItems; + mutable QWidgetList widgetItems; void updateActionRects() const; QRect popupGeometry(int screen=-1) const; mutable uint ncols : 4; //4 bits is probably plenty |