486 { |
485 { |
487 Q_Q(QMenu); |
486 Q_Q(QMenu); |
488 if (action && action->isEnabled()) { |
487 if (action && action->isEnabled()) { |
489 if (!delay) |
488 if (!delay) |
490 q->internalDelayedPopup(); |
489 q->internalDelayedPopup(); |
491 else |
490 else if (!menuDelayTimer.isActive() && (!action->menu() || !action->menu()->isVisible())) |
492 QMenuPrivate::menuDelayTimer.start(delay, q); |
491 menuDelayTimer.start(delay, q); |
493 if (activateFirst && action->menu()) |
492 if (activateFirst && action->menu()) |
494 action->menu()->d_func()->setFirstActionActive(); |
493 action->menu()->d_func()->setFirstActionActive(); |
495 } else if (QMenu *menu = activeMenu) { //hide the current item |
494 } else if (QMenu *menu = activeMenu) { //hide the current item |
496 activeMenu = 0; |
495 activeMenu = 0; |
497 hideMenu(menu); |
496 hideMenu(menu); |
542 // popup == -1 means do not popup, 0 means immediately, others mean use a timer |
541 // popup == -1 means do not popup, 0 means immediately, others mean use a timer |
543 void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason reason, bool activateFirst) |
542 void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason reason, bool activateFirst) |
544 { |
543 { |
545 Q_Q(QMenu); |
544 Q_Q(QMenu); |
546 tearoffHighlighted = 0; |
545 tearoffHighlighted = 0; |
547 if (action == currentAction) { |
|
548 if (!action || !action->menu() || action->menu() == activeMenu) { |
|
549 if(QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) { |
|
550 if(causedPopup.action && menu->d_func()->activeMenu == q) |
|
551 menu->d_func()->setCurrentAction(causedPopup.action, 0, reason, false); |
|
552 } |
|
553 } |
|
554 return; |
|
555 } |
|
556 if (currentAction) |
546 if (currentAction) |
557 q->update(actionRect(currentAction)); |
547 q->update(actionRect(currentAction)); |
558 |
548 |
559 sloppyAction = 0; |
549 sloppyAction = 0; |
560 if (!sloppyRegion.isEmpty()) |
550 if (!sloppyRegion.isEmpty()) |
1802 \sa QWidget::mapToGlobal(), exec() |
1793 \sa QWidget::mapToGlobal(), exec() |
1803 */ |
1794 */ |
1804 void QMenu::popup(const QPoint &p, QAction *atAction) |
1795 void QMenu::popup(const QPoint &p, QAction *atAction) |
1805 { |
1796 { |
1806 Q_D(QMenu); |
1797 Q_D(QMenu); |
1807 if (d->scroll) { //reset scroll state from last popup |
1798 if (d->scroll) { // reset scroll state from last popup |
1808 d->scroll->scrollOffset = 0; |
1799 d->scroll->scrollOffset = 0; |
1809 d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; |
1800 d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; |
1810 } |
1801 } |
1811 d->tearoffHighlighted = 0; |
1802 d->tearoffHighlighted = 0; |
1812 d->motions = 0; |
1803 d->motions = 0; |
1857 } |
1848 } |
1858 d->currentAction = atAction; |
1849 d->currentAction = atAction; |
1859 } |
1850 } |
1860 #endif |
1851 #endif |
1861 if (d->ncols > 1) { |
1852 if (d->ncols > 1) { |
1862 pos.setY(screen.top()+desktopFrame); |
1853 pos.setY(screen.top() + desktopFrame); |
1863 } else if (atAction) { |
1854 } else if (atAction) { |
1864 for(int i = 0, above_height = 0; i < d->actions.count(); i++) { |
1855 for (int i = 0, above_height = 0; i < d->actions.count(); i++) { |
1865 QAction *action = d->actions.at(i); |
1856 QAction *action = d->actions.at(i); |
1866 if (action == atAction) { |
1857 if (action == atAction) { |
1867 int newY = pos.y() - above_height; |
1858 int newY = pos.y() - above_height; |
1868 if (d->scroll && newY < desktopFrame) { |
1859 if (d->scroll && newY < desktopFrame) { |
1869 d->scroll->scrollFlags = d->scroll->scrollFlags |
1860 d->scroll->scrollFlags = d->scroll->scrollFlags |
1874 pos.setY(newY); |
1865 pos.setY(newY); |
1875 |
1866 |
1876 if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone |
1867 if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone |
1877 && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) { |
1868 && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) { |
1878 int below_height = above_height + d->scroll->scrollOffset; |
1869 int below_height = above_height + d->scroll->scrollOffset; |
1879 for(int i2 = i; i2 < d->actionRects.count(); i2++) |
1870 for (int i2 = i; i2 < d->actionRects.count(); i2++) |
1880 below_height += d->actionRects.at(i2).height(); |
1871 below_height += d->actionRects.at(i2).height(); |
1881 size.setHeight(below_height); |
1872 size.setHeight(below_height); |
1882 } |
1873 } |
1883 break; |
1874 break; |
1884 } else { |
1875 } else { |
1887 } |
1878 } |
1888 } |
1879 } |
1889 |
1880 |
1890 QPoint mouse = QCursor::pos(); |
1881 QPoint mouse = QCursor::pos(); |
1891 d->mousePopupPos = mouse; |
1882 d->mousePopupPos = mouse; |
1892 const bool snapToMouse = (QRect(p.x()-3, p.y()-3, 6, 6).contains(mouse)); |
1883 const bool snapToMouse = (QRect(p.x() - 3, p.y() - 3, 6, 6).contains(mouse)); |
1893 |
1884 |
1894 if (adjustToDesktop) { |
1885 if (adjustToDesktop) { |
1895 //handle popup falling "off screen" |
1886 // handle popup falling "off screen" |
1896 if (isRightToLeft()) { |
1887 if (isRightToLeft()) { |
1897 if(snapToMouse) //position flowing left from the mouse |
1888 if (snapToMouse) // position flowing left from the mouse |
1898 pos.setX(mouse.x()-size.width()); |
1889 pos.setX(mouse.x() - size.width()); |
1899 |
1890 |
1900 #ifndef QT_NO_MENUBAR |
1891 #ifndef QT_NO_MENUBAR |
1901 //if in a menubar, it should be right-aligned |
1892 // if in a menubar, it should be right-aligned |
1902 if (qobject_cast<QMenuBar*>(d->causedPopup.widget)) |
1893 if (qobject_cast<QMenuBar*>(d->causedPopup.widget)) |
1903 pos.rx() -= size.width(); |
1894 pos.rx() -= size.width(); |
1904 #endif //QT_NO_MENUBAR |
1895 #endif //QT_NO_MENUBAR |
1905 |
1896 |
1906 if (pos.x() < screen.left()+desktopFrame) |
1897 if (pos.x() < screen.left() + desktopFrame) |
1907 pos.setX(qMax(p.x(), screen.left()+desktopFrame)); |
1898 pos.setX(qMax(p.x(), screen.left() + desktopFrame)); |
1908 if (pos.x()+size.width()-1 > screen.right()-desktopFrame) |
1899 if (pos.x() + size.width() - 1 > screen.right() - desktopFrame) |
1909 pos.setX(qMax(p.x()-size.width(), screen.right()-desktopFrame-size.width()+1)); |
1900 pos.setX(qMax(p.x() - size.width(), screen.right() - desktopFrame - size.width() + 1)); |
1910 } else { |
1901 } else { |
1911 if (pos.x()+size.width()-1 > screen.right()-desktopFrame) |
1902 if (pos.x() + size.width() - 1 > screen.right() - desktopFrame) |
1912 pos.setX(screen.right()-desktopFrame-size.width()+1); |
1903 pos.setX(screen.right() - desktopFrame - size.width() + 1); |
1913 if (pos.x() < screen.left()+desktopFrame) |
1904 if (pos.x() < screen.left() + desktopFrame) |
1914 pos.setX(screen.left() + desktopFrame); |
1905 pos.setX(screen.left() + desktopFrame); |
1915 } |
1906 } |
1916 if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { |
1907 if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { |
1917 if(snapToMouse) |
1908 if(snapToMouse) |
1918 pos.setY(qMin(mouse.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1)); |
1909 pos.setY(qMin(mouse.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1)); |
1922 pos.setY(screen.top() + desktopFrame); |
1913 pos.setY(screen.top() + desktopFrame); |
1923 } |
1914 } |
1924 |
1915 |
1925 if (pos.y() < screen.top() + desktopFrame) |
1916 if (pos.y() < screen.top() + desktopFrame) |
1926 pos.setY(screen.top() + desktopFrame); |
1917 pos.setY(screen.top() + desktopFrame); |
1927 if (pos.y()+size.height()-1 > screen.bottom() - desktopFrame) { |
1918 if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { |
1928 if (d->scroll) { |
1919 if (d->scroll) { |
1929 d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown); |
1920 d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown); |
1930 int y = qMax(screen.y(),pos.y()); |
1921 int y = qMax(screen.y(),pos.y()); |
1931 size.setHeight(screen.bottom()-(desktopFrame*2)-y); |
1922 size.setHeight(screen.bottom() - (desktopFrame * 2) - y); |
1932 } else { |
1923 } else { |
1933 // Too big for screen, bias to see bottom of menu (for some reason) |
1924 // Too big for screen, bias to see bottom of menu (for some reason) |
1934 pos.setY(screen.bottom()-size.height()+1); |
1925 pos.setY(screen.bottom() - size.height() + 1); |
1935 } |
1926 } |
1936 } |
1927 } |
1937 } |
1928 } |
1938 setGeometry(QRect(pos, size)); |
1929 setGeometry(QRect(pos, size)); |
1939 #ifndef QT_NO_EFFECTS |
1930 #ifndef QT_NO_EFFECTS |
1940 int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll; |
1931 int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll; |
1941 int vGuess = QEffects::DownScroll; |
1932 int vGuess = QEffects::DownScroll; |
1942 if (isRightToLeft()) { |
1933 if (isRightToLeft()) { |
1943 if ((snapToMouse && (pos.x() + size.width()/2 > mouse.x())) || |
1934 if ((snapToMouse && (pos.x() + size.width() / 2 > mouse.x())) || |
1944 (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width()/2 > d->causedPopup.widget->x())) |
1935 (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 > d->causedPopup.widget->x())) |
1945 hGuess = QEffects::RightScroll; |
1936 hGuess = QEffects::RightScroll; |
1946 } else { |
1937 } else { |
1947 if ((snapToMouse && (pos.x() + size.width()/2 < mouse.x())) || |
1938 if ((snapToMouse && (pos.x() + size.width() / 2 < mouse.x())) || |
1948 (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width()/2 < d->causedPopup.widget->x())) |
1939 (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 < d->causedPopup.widget->x())) |
1949 hGuess = QEffects::LeftScroll; |
1940 hGuess = QEffects::LeftScroll; |
1950 } |
1941 } |
1951 |
1942 |
1952 #ifndef QT_NO_MENUBAR |
1943 #ifndef QT_NO_MENUBAR |
1953 if ((snapToMouse && (pos.y() + size.height()/2 < mouse.y())) || |
1944 if ((snapToMouse && (pos.y() + size.height() / 2 < mouse.y())) || |
1954 (qobject_cast<QMenuBar*>(d->causedPopup.widget) && |
1945 (qobject_cast<QMenuBar*>(d->causedPopup.widget) && |
1955 pos.y() + size.width()/2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y())) |
1946 pos.y() + size.width() / 2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y())) |
1956 vGuess = QEffects::UpScroll; |
1947 vGuess = QEffects::UpScroll; |
1957 #endif |
1948 #endif |
1958 if (QApplication::isEffectEnabled(Qt::UI_AnimateMenu)) { |
1949 if (QApplication::isEffectEnabled(Qt::UI_AnimateMenu)) { |
1959 bool doChildEffects = true; |
1950 bool doChildEffects = true; |
1960 #ifndef QT_NO_MENUBAR |
1951 #ifndef QT_NO_MENUBAR |
2300 d->mouseDown = 0; |
2291 d->mouseDown = 0; |
2301 d->setSyncAction(); |
2292 d->setSyncAction(); |
2302 QAction *action = d->actionAt(e->pos()); |
2293 QAction *action = d->actionAt(e->pos()); |
2303 |
2294 |
2304 if (action && action == d->currentAction) { |
2295 if (action && action == d->currentAction) { |
2305 if (action->menu()) |
2296 if (!action->menu()){ |
2306 action->menu()->d_func()->setFirstActionActive(); |
|
2307 else { |
|
2308 #if defined(Q_WS_WIN) |
2297 #if defined(Q_WS_WIN) |
2309 //On Windows only context menus can be activated with the right button |
2298 //On Windows only context menus can be activated with the right button |
2310 if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0) |
2299 if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0) |
2311 #endif |
2300 #endif |
2312 d->activateAction(action, QAction::Trigger); |
2301 d->activateAction(action, QAction::Trigger); |
2812 } else if(e->buttons()) { |
2801 } else if(e->buttons()) { |
2813 d->mouseDown = this; |
2802 d->mouseDown = this; |
2814 } |
2803 } |
2815 if (d->sloppyRegion.contains(e->pos())) { |
2804 if (d->sloppyRegion.contains(e->pos())) { |
2816 d->sloppyAction = action; |
2805 d->sloppyAction = action; |
2817 QMenuPrivate::sloppyDelayTimer.start(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6, this); |
2806 QMenuPrivate::sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6); |
2818 } else { |
2807 } else { |
2819 d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)); |
2808 d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)); |
2820 } |
2809 } |
2821 } |
2810 } |
2822 |
2811 |
2850 Q_D(QMenu); |
2839 Q_D(QMenu); |
2851 if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) { |
2840 if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) { |
2852 d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection); |
2841 d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection); |
2853 if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone) |
2842 if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone) |
2854 d->scroll->scrollTimer.stop(); |
2843 d->scroll->scrollTimer.stop(); |
2855 } else if(QMenuPrivate::menuDelayTimer.timerId() == e->timerId()) { |
2844 } else if(d->menuDelayTimer.timerId() == e->timerId()) { |
2856 QMenuPrivate::menuDelayTimer.stop(); |
2845 d->menuDelayTimer.stop(); |
2857 internalDelayedPopup(); |
2846 internalDelayedPopup(); |
2858 } else if(QMenuPrivate::sloppyDelayTimer.timerId() == e->timerId()) { |
2847 } else if(QMenuPrivate::sloppyDelayTimer == e->timerId()) { |
2859 QMenuPrivate::sloppyDelayTimer.stop(); |
2848 killTimer(QMenuPrivate::sloppyDelayTimer); |
|
2849 QMenuPrivate::sloppyDelayTimer = 0; |
2860 internalSetSloppyAction(); |
2850 internalSetSloppyAction(); |
2861 } else if(d->searchBufferTimer.timerId() == e->timerId()) { |
2851 } else if(d->searchBufferTimer.timerId() == e->timerId()) { |
2862 d->searchBuffer.clear(); |
2852 d->searchBuffer.clear(); |
2863 } |
2853 } |
2864 } |
2854 } |