src/gui/widgets/qmenu.cpp
changeset 30 5dc02b23752f
parent 29 b72c6db6890b
child 37 758a864f9613
--- a/src/gui/widgets/qmenu.cpp	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/gui/widgets/qmenu.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -85,9 +85,8 @@
 
 QT_BEGIN_NAMESPACE
 
-QPointer<QMenu> QMenuPrivate::mouseDown;
-QBasicTimer QMenuPrivate::menuDelayTimer;
-QBasicTimer QMenuPrivate::sloppyDelayTimer;
+QMenu *QMenuPrivate::mouseDown = 0;
+int QMenuPrivate::sloppyDelayTimer = 0;
 
 /* QMenu code */
 // internal class used for the torn off popup
@@ -488,8 +487,8 @@
     if (action && action->isEnabled()) {
         if (!delay)
             q->internalDelayedPopup();
-        else
-            QMenuPrivate::menuDelayTimer.start(delay, q);
+        else if (!menuDelayTimer.isActive() && (!action->menu() || !action->menu()->isVisible()))
+            menuDelayTimer.start(delay, q);
         if (activateFirst && action->menu())
             action->menu()->d_func()->setFirstActionActive();
     } else if (QMenu *menu = activeMenu) {  //hide the current item
@@ -544,15 +543,6 @@
 {
     Q_Q(QMenu);
     tearoffHighlighted = 0;
-    if (action == currentAction) {
-        if (!action || !action->menu() || action->menu() == activeMenu) {
-            if(QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) {
-                if(causedPopup.action && menu->d_func()->activeMenu == q)
-                    menu->d_func()->setCurrentAction(causedPopup.action, 0, reason, false);
-            }
-        }
-        return;
-    }
     if (currentAction)
         q->update(actionRect(currentAction));
 
@@ -566,6 +556,7 @@
 #ifdef QT3_SUPPORT
     emitHighlighted = action;
 #endif
+
     currentAction = action;
     if (action) {
         if (!action->isSeparator()) {
@@ -1804,7 +1795,7 @@
 void QMenu::popup(const QPoint &p, QAction *atAction)
 {
     Q_D(QMenu);
-    if (d->scroll) { //reset scroll state from last popup
+    if (d->scroll) { // reset scroll state from last popup
         d->scroll->scrollOffset = 0;
         d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
     }
@@ -1833,7 +1824,7 @@
     QSize size = sizeHint();
     QRect screen;
 #ifndef QT_NO_GRAPHICSVIEW
-    bool isEmbedded = d->nearestGraphicsProxyWidget(this);
+    bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this);
     if (isEmbedded)
         screen = d->popupGeometry(this);
     else
@@ -1859,9 +1850,9 @@
     }
 #endif
     if (d->ncols > 1) {
-        pos.setY(screen.top()+desktopFrame);
+        pos.setY(screen.top() + desktopFrame);
     } else if (atAction) {
-        for(int i = 0, above_height = 0; i < d->actions.count(); i++) {
+        for (int i = 0, above_height = 0; i < d->actions.count(); i++) {
             QAction *action = d->actions.at(i);
             if (action == atAction) {
                 int newY = pos.y() - above_height;
@@ -1876,7 +1867,7 @@
                 if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone
                     && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) {
                     int below_height = above_height + d->scroll->scrollOffset;
-                    for(int i2 = i; i2 < d->actionRects.count(); i2++)
+                    for (int i2 = i; i2 < d->actionRects.count(); i2++)
                         below_height += d->actionRects.at(i2).height();
                     size.setHeight(below_height);
                 }
@@ -1889,28 +1880,28 @@
 
     QPoint mouse = QCursor::pos();
     d->mousePopupPos = mouse;
-    const bool snapToMouse = (QRect(p.x()-3, p.y()-3, 6, 6).contains(mouse));
+    const bool snapToMouse = (QRect(p.x() - 3, p.y() - 3, 6, 6).contains(mouse));
 
     if (adjustToDesktop) {
-        //handle popup falling "off screen"
+        // handle popup falling "off screen"
         if (isRightToLeft()) {
-            if(snapToMouse) //position flowing left from the mouse
-                pos.setX(mouse.x()-size.width());
+            if (snapToMouse) // position flowing left from the mouse
+                pos.setX(mouse.x() - size.width());
 
 #ifndef QT_NO_MENUBAR
-            //if in a menubar, it should be right-aligned
+            // if in a menubar, it should be right-aligned
             if (qobject_cast<QMenuBar*>(d->causedPopup.widget))
                 pos.rx() -= size.width();
 #endif //QT_NO_MENUBAR
 
-            if (pos.x() < screen.left()+desktopFrame)
-                pos.setX(qMax(p.x(), screen.left()+desktopFrame));
-            if (pos.x()+size.width()-1 > screen.right()-desktopFrame)
-                pos.setX(qMax(p.x()-size.width(), screen.right()-desktopFrame-size.width()+1));
+            if (pos.x() < screen.left() + desktopFrame)
+                pos.setX(qMax(p.x(), screen.left() + desktopFrame));
+            if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)
+                pos.setX(qMax(p.x() - size.width(), screen.right() - desktopFrame - size.width() + 1));
         } else {
-            if (pos.x()+size.width()-1 > screen.right()-desktopFrame)
-                pos.setX(screen.right()-desktopFrame-size.width()+1);
-            if (pos.x() < screen.left()+desktopFrame)
+            if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)
+                pos.setX(screen.right() - desktopFrame - size.width() + 1);
+            if (pos.x() < screen.left() + desktopFrame)
                 pos.setX(screen.left() + desktopFrame);
         }
         if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) {
@@ -1924,14 +1915,14 @@
 
         if (pos.y() < screen.top() + desktopFrame)
             pos.setY(screen.top() + desktopFrame);
-        if (pos.y()+size.height()-1 > screen.bottom() - desktopFrame) {
+        if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) {
             if (d->scroll) {
                 d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown);
                 int y = qMax(screen.y(),pos.y());
-                size.setHeight(screen.bottom()-(desktopFrame*2)-y);
+                size.setHeight(screen.bottom() - (desktopFrame * 2) - y);
             } else {
                 // Too big for screen, bias to see bottom of menu (for some reason)
-                pos.setY(screen.bottom()-size.height()+1);
+                pos.setY(screen.bottom() - size.height() + 1);
             }
         }
     }
@@ -1940,19 +1931,19 @@
     int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll;
     int vGuess = QEffects::DownScroll;
     if (isRightToLeft()) {
-        if ((snapToMouse && (pos.x() + size.width()/2 > mouse.x())) ||
-           (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width()/2 > d->causedPopup.widget->x()))
+        if ((snapToMouse && (pos.x() + size.width() / 2 > mouse.x())) ||
+           (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 > d->causedPopup.widget->x()))
             hGuess = QEffects::RightScroll;
     } else {
-        if ((snapToMouse && (pos.x() + size.width()/2 < mouse.x())) ||
-           (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width()/2 < d->causedPopup.widget->x()))
+        if ((snapToMouse && (pos.x() + size.width() / 2 < mouse.x())) ||
+           (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 < d->causedPopup.widget->x()))
             hGuess = QEffects::LeftScroll;
     }
 
 #ifndef QT_NO_MENUBAR
-    if ((snapToMouse && (pos.y() + size.height()/2 < mouse.y())) ||
+    if ((snapToMouse && (pos.y() + size.height() / 2 < mouse.y())) ||
        (qobject_cast<QMenuBar*>(d->causedPopup.widget) &&
-        pos.y() + size.width()/2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y()))
+        pos.y() + size.width() / 2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y()))
        vGuess = QEffects::UpScroll;
 #endif
     if (QApplication::isEffectEnabled(Qt::UI_AnimateMenu)) {
@@ -2302,9 +2293,7 @@
     QAction *action = d->actionAt(e->pos());
 
     if (action && action == d->currentAction) {
-        if (action->menu())
-            action->menu()->d_func()->setFirstActionActive();
-        else {
+        if (!action->menu()){
 #if defined(Q_WS_WIN)
             //On Windows only context menus can be activated with the right button
             if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0)
@@ -2378,8 +2367,8 @@
         }
     } break;
     case QEvent::ContextMenu:
-        if(QMenuPrivate::menuDelayTimer.isActive()) {
-            QMenuPrivate::menuDelayTimer.stop();
+        if(d->menuDelayTimer.isActive()) {
+            d->menuDelayTimer.stop();
             internalDelayedPopup();
         }
         break;
@@ -2814,7 +2803,7 @@
     }
     if (d->sloppyRegion.contains(e->pos())) {
         d->sloppyAction = action;
-        QMenuPrivate::sloppyDelayTimer.start(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6, this);
+        QMenuPrivate::sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6);
     } else {
         d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this));
     }
@@ -2852,11 +2841,12 @@
         d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection);
         if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone)
             d->scroll->scrollTimer.stop();
-    } else if(QMenuPrivate::menuDelayTimer.timerId() == e->timerId()) {
-        QMenuPrivate::menuDelayTimer.stop();
+    } else if(d->menuDelayTimer.timerId() == e->timerId()) {
+        d->menuDelayTimer.stop();
         internalDelayedPopup();
-    } else if(QMenuPrivate::sloppyDelayTimer.timerId() == e->timerId()) {
-        QMenuPrivate::sloppyDelayTimer.stop();
+    } else if(QMenuPrivate::sloppyDelayTimer == e->timerId()) {
+        killTimer(QMenuPrivate::sloppyDelayTimer);
+        QMenuPrivate::sloppyDelayTimer = 0;
         internalSetSloppyAction();
     } else if(d->searchBufferTimer.timerId() == e->timerId()) {
         d->searchBuffer.clear();