63 |
63 |
64 #include "qmenu_p.h" |
64 #include "qmenu_p.h" |
65 #include "qmenubar_p.h" |
65 #include "qmenubar_p.h" |
66 #include "qwidgetaction.h" |
66 #include "qwidgetaction.h" |
67 #include "qtoolbutton.h" |
67 #include "qtoolbutton.h" |
|
68 #include "qpushbutton.h" |
|
69 #include <private/qpushbutton_p.h> |
68 #include <private/qaction_p.h> |
70 #include <private/qaction_p.h> |
69 #include <private/qsoftkeymanager_p.h> |
71 #include <private/qsoftkeymanager_p.h> |
70 #ifdef QT3_SUPPORT |
72 #ifdef QT3_SUPPORT |
71 #include <qmenudata.h> |
73 #include <qmenudata.h> |
72 #endif // QT3_SUPPORT |
74 #endif // QT3_SUPPORT |
271 ncols = 1; |
273 ncols = 1; |
272 sloppyAction = 0; |
274 sloppyAction = 0; |
273 |
275 |
274 for (int i = 0; i < actions.count(); ++i) { |
276 for (int i = 0; i < actions.count(); ++i) { |
275 QAction *action = actions.at(i); |
277 QAction *action = actions.at(i); |
276 if (action->isSeparator() || !action->isVisible() || widgetItems.at(i)) |
278 if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action)) |
277 continue; |
279 continue; |
278 //..and some members |
280 //..and some members |
279 hasCheckableItems |= action->isCheckable(); |
281 hasCheckableItems |= action->isCheckable(); |
280 QIcon is = action->icon(); |
282 QIcon is = action->icon(); |
281 if (!is.isNull()) { |
283 if (!is.isNull()) { |
290 QAction *action = actions.at(i); |
292 QAction *action = actions.at(i); |
291 |
293 |
292 if (!action->isVisible() || |
294 if (!action->isVisible() || |
293 (collapsibleSeparators && previousWasSeparator && action->isSeparator())) |
295 (collapsibleSeparators && previousWasSeparator && action->isSeparator())) |
294 continue; // we continue, this action will get an empty QRect |
296 continue; // we continue, this action will get an empty QRect |
295 |
297 |
296 previousWasSeparator = action->isSeparator(); |
298 previousWasSeparator = action->isSeparator(); |
297 |
299 |
298 //let the style modify the above size.. |
300 //let the style modify the above size.. |
299 QStyleOptionMenuItem opt; |
301 QStyleOptionMenuItem opt; |
300 q->initStyleOption(&opt, action); |
302 q->initStyleOption(&opt, action); |
301 const QFontMetrics &fm = opt.fontMetrics; |
303 const QFontMetrics &fm = opt.fontMetrics; |
302 |
304 |
303 QSize sz; |
305 QSize sz; |
304 if (QWidget *w = widgetItems.at(i)) { |
306 if (QWidget *w = widgetItems.value(action)) { |
305 sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize()); |
307 sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize()); |
306 } else { |
308 } else { |
307 //calc what I think the size is.. |
309 //calc what I think the size is.. |
308 if (action->isSeparator()) { |
310 if (action->isSeparator()) { |
309 sz = QSize(2, 2); |
311 sz = QSize(2, 2); |
368 } |
370 } |
369 rect.translate(x, y); //move |
371 rect.translate(x, y); //move |
370 rect.setWidth(max_column_width); //uniform width |
372 rect.setWidth(max_column_width); //uniform width |
371 |
373 |
372 //we need to update the widgets geometry |
374 //we need to update the widgets geometry |
373 if (QWidget *widget = widgetItems.at(i)) { |
375 if (QWidget *widget = widgetItems.value(actions.at(i))) { |
374 widget->setGeometry(rect); |
376 widget->setGeometry(rect); |
375 widget->setVisible(actions.at(i)->isVisible()); |
377 widget->setVisible(actions.at(i)->isVisible()); |
376 } |
378 } |
377 |
379 |
378 y += rect.height(); |
380 y += rect.height(); |
415 caused = m->d_func()->causedPopup.widget; |
417 caused = m->d_func()->causedPopup.widget; |
416 if (!m->d_func()->tornoff) |
418 if (!m->d_func()->tornoff) |
417 hideMenu(m, fadeMenus); |
419 hideMenu(m, fadeMenus); |
418 if (!fadeMenus) // Mac doesn't clear the action until after hidden. |
420 if (!fadeMenus) // Mac doesn't clear the action until after hidden. |
419 m->d_func()->setCurrentAction(0); |
421 m->d_func()->setCurrentAction(0); |
420 } else { |
422 } else { caused = 0; |
421 #ifndef QT_NO_TOOLBUTTON |
|
422 if (qobject_cast<QToolButton*>(caused) == 0) |
|
423 #endif |
|
424 qWarning("QMenu: Internal error"); |
|
425 caused = 0; |
|
426 } |
423 } |
427 } |
424 } |
428 #if defined(Q_WS_MAC) |
425 #if defined(Q_WS_MAC) |
429 if (fadeMenus) { |
426 if (fadeMenus) { |
430 QEventLoop eventLoop; |
427 QEventLoop eventLoop; |
581 popupAction(currentAction, popup, activateFirst); |
578 popupAction(currentAction, popup, activateFirst); |
582 } |
579 } |
583 q->update(actionRect(action)); |
580 q->update(actionRect(action)); |
584 |
581 |
585 if (reason == SelectedFromKeyboard) { |
582 if (reason == SelectedFromKeyboard) { |
586 const int actionIndex = actions.indexOf(action); |
583 QWidget *widget = widgetItems.value(action); |
587 QWidget *widget = widgetItems.at(actionIndex); |
|
588 if (widget) { |
584 if (widget) { |
589 if (widget->focusPolicy() != Qt::NoFocus) |
585 if (widget->focusPolicy() != Qt::NoFocus) |
590 widget->setFocus(Qt::TabFocusReason); |
586 widget->setFocus(Qt::TabFocusReason); |
591 } else { |
587 } else { |
592 //when the action has no QWidget, the QMenu itself should |
588 //when the action has no QWidget, the QMenu itself should |
601 if (popup != -1) |
597 if (popup != -1) |
602 hideActiveMenu = 0; //will be done "later" |
598 hideActiveMenu = 0; //will be done "later" |
603 } |
599 } |
604 #ifndef QT_NO_STATUSTIP |
600 #ifndef QT_NO_STATUSTIP |
605 } else if (previousAction) { |
601 } else if (previousAction) { |
606 QWidget *w = causedPopup.widget; |
602 previousAction->d_func()->showStatusText(topCausedWidget(), QString()); |
607 while (QMenu *m = qobject_cast<QMenu*>(w)) |
|
608 w = m->d_func()->causedPopup.widget; |
|
609 if (w) { |
|
610 QString empty; |
|
611 QStatusTipEvent tip(empty); |
|
612 QApplication::sendEvent(w, &tip); |
|
613 } |
|
614 #endif |
603 #endif |
615 } |
604 } |
616 if (hideActiveMenu) { |
605 if (hideActiveMenu) { |
617 activeMenu = 0; |
606 activeMenu = 0; |
618 #ifndef QT_NO_EFFECTS |
607 #ifndef QT_NO_EFFECTS |
620 qFadeEffect(0); |
609 qFadeEffect(0); |
621 qScrollEffect(0); |
610 qScrollEffect(0); |
622 #endif |
611 #endif |
623 hideMenu(hideActiveMenu); |
612 hideMenu(hideActiveMenu); |
624 } |
613 } |
|
614 } |
|
615 |
|
616 //return the top causedPopup.widget that is not a QMenu |
|
617 QWidget *QMenuPrivate::topCausedWidget() const |
|
618 { |
|
619 QWidget* top = causedPopup.widget; |
|
620 while (QMenu* m = qobject_cast<QMenu *>(top)) |
|
621 top = m->d_func()->causedPopup.widget; |
|
622 return top; |
625 } |
623 } |
626 |
624 |
627 QAction *QMenuPrivate::actionAt(QPoint p) const |
625 QAction *QMenuPrivate::actionAt(QPoint p) const |
628 { |
626 { |
629 if (!q_func()->rect().contains(p)) //sanity check |
627 if (!q_func()->rect().contains(p)) //sanity check |
650 |
648 |
651 void QMenuPrivate::_q_overrideMenuActionDestroyed() |
649 void QMenuPrivate::_q_overrideMenuActionDestroyed() |
652 { |
650 { |
653 menuAction=defaultMenuAction; |
651 menuAction=defaultMenuAction; |
654 } |
652 } |
|
653 |
|
654 |
|
655 void QMenuPrivate::updateLayoutDirection() |
|
656 { |
|
657 Q_Q(QMenu); |
|
658 //we need to mimic the cause of the popup's layout direction |
|
659 //to allow setting it on a mainwindow for example |
|
660 //we call setLayoutDirection_helper to not overwrite a user-defined value |
|
661 if (!q->testAttribute(Qt::WA_SetLayoutDirection)) { |
|
662 if (QWidget *w = causedPopup.widget) |
|
663 setLayoutDirection_helper(w->layoutDirection()); |
|
664 else if (QWidget *w = q->parentWidget()) |
|
665 setLayoutDirection_helper(w->layoutDirection()); |
|
666 else |
|
667 setLayoutDirection_helper(QApplication::layoutDirection()); |
|
668 } |
|
669 } |
|
670 |
655 |
671 |
656 /*! |
672 /*! |
657 Returns the action associated with this menu. |
673 Returns the action associated with this menu. |
658 */ |
674 */ |
659 QAction *QMenu::menuAction() const |
675 QAction *QMenu::menuAction() const |
798 for (int i = 0; i < actionRects.count(); ++i) { |
814 for (int i = 0; i < actionRects.count(); ++i) { |
799 QRect ¤t = actionRects[i]; |
815 QRect ¤t = actionRects[i]; |
800 current.moveTop(current.top() + delta); |
816 current.moveTop(current.top() + delta); |
801 |
817 |
802 //we need to update the widgets geometry |
818 //we need to update the widgets geometry |
803 if (QWidget *w = widgetItems.at(i)) |
819 if (QWidget *w = widgetItems.value(actions.at(i))) |
804 w->setGeometry(current); |
820 w->setGeometry(current); |
805 } |
821 } |
806 } |
822 } |
807 scroll->scrollOffset += delta; |
823 scroll->scrollOffset += delta; |
808 scroll->scrollFlags = newScrollFlags; |
824 scroll->scrollFlags = newScrollFlags; |
1093 int actionIndex = indexOf(action) + 1; |
1109 int actionIndex = indexOf(action) + 1; |
1094 QAccessible::updateAccessibility(q, actionIndex, QAccessible::Focus); |
1110 QAccessible::updateAccessibility(q, actionIndex, QAccessible::Focus); |
1095 QAccessible::updateAccessibility(q, actionIndex, QAccessible::Selection); |
1111 QAccessible::updateAccessibility(q, actionIndex, QAccessible::Selection); |
1096 } |
1112 } |
1097 #endif |
1113 #endif |
1098 QWidget *w = causedPopup.widget; |
1114 action->showStatusText(topCausedWidget()); |
1099 while (QMenu *m = qobject_cast<QMenu*>(w)) |
|
1100 w = m->d_func()->causedPopup.widget; |
|
1101 action->showStatusText(w); |
|
1102 } else { |
1115 } else { |
1103 actionAboutToTrigger = 0; |
1116 actionAboutToTrigger = 0; |
1104 } |
1117 } |
1105 } |
1118 } |
1106 |
1119 |
1107 void QMenuPrivate::_q_actionTriggered() |
1120 void QMenuPrivate::_q_actionTriggered() |
1108 { |
1121 { |
1109 Q_Q(QMenu); |
1122 Q_Q(QMenu); |
1110 if (QAction *action = qobject_cast<QAction *>(q->sender())) { |
1123 if (QAction *action = qobject_cast<QAction *>(q->sender())) { |
|
1124 QWeakPointer<QAction> actionGuard = action; |
1111 #ifdef QT3_SUPPORT |
1125 #ifdef QT3_SUPPORT |
1112 //we store it here because the action might be deleted/changed by connected slots |
1126 //we store it here because the action might be deleted/changed by connected slots |
1113 const int id = q->findIdForAction(action); |
1127 const int id = q->findIdForAction(action); |
1114 #endif |
1128 #endif |
1115 emit q->triggered(action); |
1129 emit q->triggered(action); |
1116 #ifdef QT3_SUPPORT |
1130 #ifdef QT3_SUPPORT |
1117 emit q->activated(id); |
1131 emit q->activated(id); |
1118 #endif |
1132 #endif |
1119 |
1133 |
1120 if (!activationRecursionGuard) { |
1134 if (!activationRecursionGuard && actionGuard) { |
1121 //in case the action has not been activated by the mouse |
1135 //in case the action has not been activated by the mouse |
1122 //we check the parent hierarchy |
1136 //we check the parent hierarchy |
1123 QList< QPointer<QWidget> > list; |
1137 QList< QPointer<QWidget> > list; |
1124 for(QWidget *widget = q->parentWidget(); widget; ) { |
1138 for(QWidget *widget = q->parentWidget(); widget; ) { |
1125 if (qobject_cast<QMenu*>(widget) |
1139 if (qobject_cast<QMenu*>(widget) |
1126 #ifndef QT_NO_MENUBAR |
1140 #ifndef QT_NO_MENUBAR |
1127 || qobject_cast<QMenuBar*>(widget) |
1141 || qobject_cast<QMenuBar*>(widget) |
1128 #endif |
1142 #endif |
1129 ) { |
1143 ) { |
1130 list.append(widget); |
1144 list.append(widget); |
1287 |
1301 |
1288 A menu consists of a list of action items. Actions are added with |
1302 A menu consists of a list of action items. Actions are added with |
1289 the addAction(), addActions() and insertAction() functions. An action |
1303 the addAction(), addActions() and insertAction() functions. An action |
1290 is represented vertically and rendered by QStyle. In addition, actions |
1304 is represented vertically and rendered by QStyle. In addition, actions |
1291 can have a text label, an optional icon drawn on the very left side, |
1305 can have a text label, an optional icon drawn on the very left side, |
1292 and shortcut key sequence such as "Ctrl+X". |
1306 and shortcut key sequence such as "Ctrl+X". |
1293 |
1307 |
1294 The existing actions held by a menu can be found with actions(). |
1308 The existing actions held by a menu can be found with actions(). |
1295 |
1309 |
1296 There are four kinds of action items: separators, actions that |
1310 There are four kinds of action items: separators, actions that |
1297 show a submenu, widgets, and actions that perform an action. |
1311 show a submenu, widgets, and actions that perform an action. |
1390 Destroys the menu. |
1404 Destroys the menu. |
1391 */ |
1405 */ |
1392 QMenu::~QMenu() |
1406 QMenu::~QMenu() |
1393 { |
1407 { |
1394 Q_D(QMenu); |
1408 Q_D(QMenu); |
1395 for (int i = 0; i < d->widgetItems.count(); ++i) { |
1409 QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin(); |
1396 if (QWidget *widget = d->widgetItems.at(i)) { |
1410 for (; it != d->widgetItems.end(); ++it) { |
1397 QWidgetAction *action = static_cast<QWidgetAction *>(d->actions.at(i)); |
1411 if (QWidget *widget = it.value()) { |
|
1412 QWidgetAction *action = static_cast<QWidgetAction *>(it.key()); |
1398 action->releaseWidget(widget); |
1413 action->releaseWidget(widget); |
1399 d->widgetItems[i] = 0; |
1414 *it = 0; |
1400 } |
1415 } |
1401 } |
1416 } |
1402 |
1417 |
1403 if (d->eventLoop) |
1418 if (d->eventLoop) |
1404 d->eventLoop->exit(); |
1419 d->eventLoop->exit(); |
1795 d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; |
1810 d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; |
1796 } |
1811 } |
1797 d->tearoffHighlighted = 0; |
1812 d->tearoffHighlighted = 0; |
1798 d->motions = 0; |
1813 d->motions = 0; |
1799 d->doChildEffects = true; |
1814 d->doChildEffects = true; |
|
1815 d->updateLayoutDirection(); |
1800 |
1816 |
1801 #ifndef QT_NO_MENUBAR |
1817 #ifndef QT_NO_MENUBAR |
1802 // if this menu is part of a chain attached to a QMenuBar, set the |
1818 // if this menu is part of a chain attached to a QMenuBar, set the |
1803 // _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type |
1819 // _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type |
1804 QWidget* top = this; |
1820 setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(d->topCausedWidget()) != 0); |
1805 while (QMenu* m = qobject_cast<QMenu *>(top)) |
|
1806 top = m->d_func()->causedPopup.widget; |
|
1807 setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(top) != 0); |
|
1808 #endif |
1821 #endif |
1809 |
1822 |
1810 ensurePolished(); // Get the right font |
1823 ensurePolished(); // Get the right font |
1811 emit aboutToShow(); |
1824 emit aboutToShow(); |
|
1825 const bool actionListChanged = d->itemsDirty; |
1812 d->updateActionRects(); |
1826 d->updateActionRects(); |
1813 QPoint pos = p; |
1827 QPoint pos; |
|
1828 QPushButton *causedButton = qobject_cast<QPushButton*>(d->causedPopup.widget); |
|
1829 if (actionListChanged && causedButton) |
|
1830 pos = QPushButtonPrivate::get(causedButton)->adjustedMenuPosition(); |
|
1831 else |
|
1832 pos = p; |
|
1833 |
1814 QSize size = sizeHint(); |
1834 QSize size = sizeHint(); |
1815 QRect screen; |
1835 QRect screen; |
1816 #ifndef QT_NO_GRAPHICSVIEW |
1836 #ifndef QT_NO_GRAPHICSVIEW |
1817 bool isEmbedded = d->nearestGraphicsProxyWidget(this); |
1837 bool isEmbedded = d->nearestGraphicsProxyWidget(this); |
1818 if (isEmbedded) |
1838 if (isEmbedded) |
1876 //handle popup falling "off screen" |
1896 //handle popup falling "off screen" |
1877 if (isRightToLeft()) { |
1897 if (isRightToLeft()) { |
1878 if(snapToMouse) //position flowing left from the mouse |
1898 if(snapToMouse) //position flowing left from the mouse |
1879 pos.setX(mouse.x()-size.width()); |
1899 pos.setX(mouse.x()-size.width()); |
1880 |
1900 |
|
1901 #ifndef QT_NO_MENUBAR |
|
1902 //if in a menubar, it should be right-aligned |
|
1903 if (qobject_cast<QMenuBar*>(d->causedPopup.widget)) |
|
1904 pos.rx() -= size.width(); |
|
1905 #endif //QT_NO_MENUBAR |
|
1906 |
1881 if (pos.x() < screen.left()+desktopFrame) |
1907 if (pos.x() < screen.left()+desktopFrame) |
1882 pos.setX(qMax(p.x(), screen.left()+desktopFrame)); |
1908 pos.setX(qMax(p.x(), screen.left()+desktopFrame)); |
1883 if (pos.x()+size.width()-1 > screen.right()-desktopFrame) |
1909 if (pos.x()+size.width()-1 > screen.right()-desktopFrame) |
1884 pos.setX(qMax(p.x()-size.width(), screen.right()-desktopFrame-size.width()+1)); |
1910 pos.setX(qMax(p.x()-size.width(), screen.right()-desktopFrame-size.width()+1)); |
1885 } else { |
1911 } else { |
1886 if (pos.x()+size.width()-1 > screen.right()-desktopFrame) |
1912 if (pos.x()+size.width()-1 > screen.right()-desktopFrame) |
1887 pos.setX(qMin(p.x()+size.width(), screen.right()-desktopFrame-size.width()+1)); |
1913 pos.setX(screen.right()-desktopFrame-size.width()+1); |
1888 if (pos.x() < screen.left()+desktopFrame) |
1914 if (pos.x() < screen.left()+desktopFrame) |
1889 pos.setX(qMax(p.x(), screen.left() + desktopFrame)); |
1915 pos.setX(screen.left() + desktopFrame); |
1890 } |
1916 } |
1891 if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { |
1917 if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { |
1892 if(snapToMouse) |
1918 if(snapToMouse) |
1893 pos.setY(qMin(mouse.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1)); |
1919 pos.setY(qMin(mouse.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1)); |
1894 else |
1920 else |
2145 //draw the items that need updating.. |
2171 //draw the items that need updating.. |
2146 for (int i = 0; i < d->actions.count(); ++i) { |
2172 for (int i = 0; i < d->actions.count(); ++i) { |
2147 QAction *action = d->actions.at(i); |
2173 QAction *action = d->actions.at(i); |
2148 QRect adjustedActionRect = d->actionRects.at(i); |
2174 QRect adjustedActionRect = d->actionRects.at(i); |
2149 if (!e->rect().intersects(adjustedActionRect) |
2175 if (!e->rect().intersects(adjustedActionRect) |
2150 || d->widgetItems.at(i)) |
2176 || d->widgetItems.value(action)) |
2151 continue; |
2177 continue; |
2152 //set the clip region to be extra safe (and adjust for the scrollers) |
2178 //set the clip region to be extra safe (and adjust for the scrollers) |
2153 QRegion adjustedActionReg(adjustedActionRect); |
2179 QRegion adjustedActionReg(adjustedActionRect); |
2154 emptyArea -= adjustedActionReg; |
2180 emptyArea -= adjustedActionReg; |
2155 p.setClipRegion(adjustedActionReg); |
2181 p.setClipRegion(adjustedActionReg); |
2278 |
2304 |
2279 if (action && action == d->currentAction) { |
2305 if (action && action == d->currentAction) { |
2280 if (action->menu()) |
2306 if (action->menu()) |
2281 action->menu()->d_func()->setFirstActionActive(); |
2307 action->menu()->d_func()->setFirstActionActive(); |
2282 else { |
2308 else { |
2283 #if defined(Q_WS_WIN) && !defined(QT_NO_MENUBAR) |
2309 #if defined(Q_WS_WIN) |
2284 //On Windows only context menus can be activated with the right button |
2310 //On Windows only context menus can be activated with the right button |
2285 bool isContextMenu = true; |
2311 if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0) |
2286 const QWidget *cause = d->causedPopup.widget; |
|
2287 while (cause) { |
|
2288 //if the popup was caused by either QMenuBar or a QToolButton, it is not a context menu |
|
2289 if (qobject_cast<const QMenuBar *>(cause) || qobject_cast<const QToolButton *>(cause)) { |
|
2290 isContextMenu = false; |
|
2291 break; |
|
2292 } else if (const QMenu *menu = qobject_cast<const QMenu *>(cause)) { |
|
2293 cause = menu->d_func()->causedPopup.widget; |
|
2294 } else { |
|
2295 break; |
|
2296 } |
|
2297 } |
|
2298 if (e->button() == Qt::LeftButton || isContextMenu) |
|
2299 #endif |
2312 #endif |
2300 d->activateAction(action, QAction::Trigger); |
2313 d->activateAction(action, QAction::Trigger); |
2301 } |
2314 } |
2302 } else if (d->hasMouseMoved(e->globalPos())) { |
2315 } else if (d->hasMouseMoved(e->globalPos())) { |
2303 d->hideUpToMenuBar(); |
2316 d->hideUpToMenuBar(); |
2342 bool |
2355 bool |
2343 QMenu::event(QEvent *e) |
2356 QMenu::event(QEvent *e) |
2344 { |
2357 { |
2345 Q_D(QMenu); |
2358 Q_D(QMenu); |
2346 switch (e->type()) { |
2359 switch (e->type()) { |
|
2360 case QEvent::Polish: |
|
2361 d->updateLayoutDirection(); |
|
2362 break; |
2347 case QEvent::ShortcutOverride: { |
2363 case QEvent::ShortcutOverride: { |
2348 QKeyEvent *kev = static_cast<QKeyEvent*>(e); |
2364 QKeyEvent *kev = static_cast<QKeyEvent*>(e); |
2349 if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down |
2365 if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down |
2350 || kev->key() == Qt::Key_Left || kev->key() == Qt::Key_Right |
2366 || kev->key() == Qt::Key_Left || kev->key() == Qt::Key_Right |
2351 || kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return |
2367 || kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return |
2744 d->activateAction(nextAction, QAction::Trigger); |
2760 d->activateAction(nextAction, QAction::Trigger); |
2745 } |
2761 } |
2746 } |
2762 } |
2747 } |
2763 } |
2748 if (!key_consumed) { |
2764 if (!key_consumed) { |
2749 if (QWidget *caused = d->causedPopup.widget) { |
|
2750 while(QMenu *m = qobject_cast<QMenu*>(caused)) |
|
2751 caused = m->d_func()->causedPopup.widget; |
|
2752 #ifndef QT_NO_MENUBAR |
2765 #ifndef QT_NO_MENUBAR |
2753 if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) { |
2766 if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->topCausedWidget())) { |
2754 QAction *oldAct = mb->d_func()->currentAction; |
2767 QAction *oldAct = mb->d_func()->currentAction; |
2755 QApplication::sendEvent(mb, e); |
2768 QApplication::sendEvent(mb, e); |
2756 if (mb->d_func()->currentAction != oldAct) |
2769 if (mb->d_func()->currentAction != oldAct) |
2757 key_consumed = true; |
2770 key_consumed = true; |
2758 } |
|
2759 #endif |
|
2760 } |
2771 } |
|
2772 #endif |
2761 } |
2773 } |
2762 |
2774 |
2763 #ifdef Q_OS_WIN32 |
2775 #ifdef Q_OS_WIN32 |
2764 if (key_consumed && (e->key() == Qt::Key_Control || e->key() == Qt::Key_Shift || e->key() == Qt::Key_Meta)) |
2776 if (key_consumed && (e->key() == Qt::Key_Control || e->key() == Qt::Key_Shift || e->key() == Qt::Key_Meta)) |
2765 QApplication::beep(); |
2777 QApplication::beep(); |
2856 if (e->type() == QEvent::ActionAdded) { |
2868 if (e->type() == QEvent::ActionAdded) { |
2857 if(!d->tornoff) { |
2869 if(!d->tornoff) { |
2858 connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered())); |
2870 connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered())); |
2859 connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered())); |
2871 connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered())); |
2860 } |
2872 } |
2861 QWidget *widget = 0; |
2873 if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) { |
2862 if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) |
2874 QWidget *widget = wa->requestWidget(this); |
2863 widget = wa->requestWidget(this); |
2875 if (widget) |
2864 |
2876 d->widgetItems.insert(wa, widget); |
2865 int index = d->actions.indexOf(e->action()); |
2877 } |
2866 Q_ASSERT(index != -1); |
|
2867 d->widgetItems.insert(index, widget); |
|
2868 |
|
2869 } else if (e->type() == QEvent::ActionRemoved) { |
2878 } else if (e->type() == QEvent::ActionRemoved) { |
2870 e->action()->disconnect(this); |
2879 e->action()->disconnect(this); |
2871 if (e->action() == d->currentAction) |
2880 if (e->action() == d->currentAction) |
2872 d->currentAction = 0; |
2881 d->currentAction = 0; |
2873 int index = d->actions.indexOf(e->before()) + 1; |
|
2874 if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) { |
2882 if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) { |
2875 if (QWidget *widget = d->widgetItems.at(index)) |
2883 if (QWidget *widget = d->widgetItems.value(wa)) |
2876 wa->releaseWidget(widget); |
2884 wa->releaseWidget(widget); |
2877 } |
2885 } |
2878 Q_ASSERT(index != -1); |
2886 d->widgetItems.remove(e->action()); |
2879 d->widgetItems.removeAt(index); |
|
2880 } |
2887 } |
2881 |
2888 |
2882 #ifdef Q_WS_MAC |
2889 #ifdef Q_WS_MAC |
2883 if (d->mac_menu) { |
2890 if (d->mac_menu) { |
2884 if (e->type() == QEvent::ActionAdded) |
2891 if (e->type() == QEvent::ActionAdded) |