qmenu.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/widgets/qmenu.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4-
5-
6-
7-
8-
9-
10-
11-
12-
13-
14-
15-
16-
17QMenu *QMenuPrivate::mouseDown = 0;-
18-
19-
20-
21class QTornOffMenu : public QMenu-
22{-
23 public: template <typename ThisObject> inline void qt_check_for_QOBJECT_macro(const ThisObject &_q_argument) const { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i + 1; }-
24#pragma GCC diagnostic push-
25 static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); static inline QString tr(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } __attribute__ ((__deprecated__)) static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } private: __attribute__((visibility("hidden"))) static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);-
26#pragma GCC diagnostic pop-
27 struct QPrivateSignal {};-
28 class QTornOffMenuPrivate : public QMenuPrivate-
29 {-
30 inline QMenu* q_func() { return static_cast<QMenu *>(q_ptr); } inline const QMenu* q_func() const { return static_cast<const QMenu *>(q_ptr); } friend class QMenu;-
31 public:-
32 QTornOffMenuPrivate(QMenu *p) : causedMenu(p) {-
33 tornoff = 1;-
34 causedPopup.widget = 0;-
35 causedPopup.action = ((QTornOffMenu*)p)->d_func()->causedPopup.action;-
36 causedStack = ((QTornOffMenu*)p)->d_func()->calcCausedStack();-
37 }-
38 QVector<QPointer<QWidget> > calcCausedStack() const override { return causedStack; }-
39 QPointer<QMenu> causedMenu;-
40 QVector<QPointer<QWidget> > causedStack;-
41 };-
42public:-
43 QTornOffMenu(QMenu *p) : QMenu(*(new QTornOffMenuPrivate(p)))-
44 {-
45 QTornOffMenuPrivate * const d = d_func();-
46-
47 QWidget *parentWidget = d->causedStack.isEmpty()
d->causedStack.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
? p : d->causedStack.lastconstLast();
0
48 if (parentWidget->parentWidget()
parentWidget->parentWidget()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
49 parentWidget = parentWidget->parentWidget();
never executed: parentWidget = parentWidget->parentWidget();
0
50 setParent(parentWidget, Qt::Window | Qt::Tool);-
51 setAttribute(Qt::WA_DeleteOnClose, true);-
52 setAttribute(Qt::WA_X11NetWmWindowTypeMenu, true);-
53 setWindowTitle(p->windowTitle());-
54 setEnabled(p->isEnabled());-
55-
56-
57 QList<QAction*> items = p->actions();-
58 for(int i = 0; i < items.count()
i < items.count()Description
TRUEnever evaluated
FALSEnever evaluated
; i++)
0
59 addAction(items.at(i));
never executed: addAction(items.at(i));
0
60 }
never executed: end of block
0
61 void syncWithMenu(QMenu *menu, QActionEvent *act)-
62 {-
63 QTornOffMenuPrivate * const d = d_func();-
64 if(menu != d->causedMenu)-
65 return;-
66 if (act->type() == QEvent::ActionAdded) {-
67 insertAction(act->before(), act->action());-
68 } else if (act->type() == QEvent::ActionRemoved)-
69 removeAction(act->action());-
70 }-
71 void actionEvent(QActionEvent *e) override-
72 {-
73 QMenu::actionEvent(e);-
74 setFixedSize(sizeHint());-
75 }-
76public :-
77 void onTrigger(QAction *action) { d_func()->activateAction(action, QAction::Trigger, false); }-
78 void onHovered(QAction *action) { d_func()->activateAction(action, QAction::Hover, false); }-
79private:-
80 inline QTornOffMenuPrivate* d_func() { return reinterpret_cast<QTornOffMenuPrivate *>(qGetPtrHelper(d_ptr)); } inline const QTornOffMenuPrivate* d_func() const { return reinterpret_cast<const QTornOffMenuPrivate *>(qGetPtrHelper(d_ptr)); } friend class QTornOffMenuPrivate;-
81 friend class QMenuPrivate;-
82};-
83-
84void QMenuPrivate::init()-
85{-
86 QMenu * const q = q_func();-
87-
88 q->setAttribute(Qt::WA_CustomWhatsThis);-
89-
90 q->setAttribute(Qt::WA_X11NetWmWindowTypePopupMenu);-
91 defaultMenuAction = menuAction = new QAction(q);-
92 menuAction->d_func()->menu = q;-
93 q->setMouseTracking(q->style()->styleHint(QStyle::SH_Menu_MouseTracking, 0, q));-
94 if (q->style()->styleHint(QStyle::SH_Menu_Scrollable, 0, q)) {-
95 scroll = new QMenuPrivate::QMenuScroller;-
96 scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;-
97 }-
98-
99 setPlatformMenu(QGuiApplicationPrivate::platformTheme()->createPlatformMenu());-
100 sloppyState.initialize(q);-
101 delayState.initialize(q);-
102 mousePopupDelay = q->style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, q);-
103}-
104-
105void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu)-
106{-
107 QMenu * const q = q_func();-
108 if (!platformMenu.isNull() && !platformMenu->parent())-
109 delete platformMenu.data();-
110-
111 platformMenu = menu;-
112 if (!platformMenu.isNull()) {-
113 QObject::connect(platformMenu, qFlagLocation("2""aboutToShow()" "\0" __FILE__ ":" "164""170"), q, qFlagLocation("1""_q_platformMenuAboutToShow()" "\0" __FILE__ ":" "164""170"));-
114 QObject::connect(platformMenu, qFlagLocation("2""aboutToHide()" "\0" __FILE__ ":" "165""171"), q, qFlagLocation("2""aboutToHide()" "\0" __FILE__ ":" "165""171"));-
115 }-
116}-
117-
118-
119static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item, QPlatformMenu *itemsMenu);-
120-
121void QMenuPrivate::syncPlatformMenu()-
122{-
123 QMenu * const q = q_func();-
124 if (platformMenu.isNull())-
125 return;-
126-
127 QPlatformMenuItem *beforeItem = nullptr;-
128 const QList<QAction*> actions = q->actions();-
129 for (QList<QAction*>::const_reverse_iterator it = actions.rbegin(), end = actions.rend(); it != end; ++it) {-
130 QPlatformMenuItem *menuItem = platformMenu->createMenuItem();-
131 QAction *action = *it;-
132 menuItem->setTag(reinterpret_cast<quintptr>(action));-
133 QObject::connect(menuItem, qFlagLocation("2""activated()" "\0" __FILE__ ":" "184""190"), action, qFlagLocation("1""trigger()" "\0" __FILE__ ":" "184""190"), Qt::QueuedConnection);-
134 QObject::connect(menuItem, qFlagLocation("2""hovered()" "\0" __FILE__ ":" "185""191"), action, qFlagLocation("2""hovered()" "\0" __FILE__ ":" "185""191"), Qt::QueuedConnection);-
135 copyActionToPlatformItem(action, menuItem, platformMenu.data());-
136 platformMenu->insertMenuItem(menuItem, beforeItem);-
137 beforeItem = menuItem;-
138 }-
139 platformMenu->syncSeparatorsCollapsible(collapsibleSeparators);-
140 platformMenu->setEnabled(q->isEnabled());-
141}-
142-
143int QMenuPrivate::scrollerHeight() const-
144{-
145 const QMenu * const q = q_func();-
146 return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));-
147}-
148-
149-
150QRect QMenuPrivate::popupGeometry(const QWidget *widget) const-
151{-
152 if (QGuiApplicationPrivate::platformTheme() &&-
153 QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::UseFullScreenForPopupMenu).toBool()) {-
154 return QApplication::desktop()->screenGeometry(widget);-
155 } else {-
156 return QApplication::desktop()->availableGeometry(widget);-
157 }-
158}-
159-
160-
161QRect QMenuPrivate::popupGeometry(int screen) const-
162{-
163 if (QGuiApplicationPrivate::platformTheme() &&-
164 QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::UseFullScreenForPopupMenu).toBool()) {-
165 return QApplication::desktop()->screenGeometry(screen);-
166 } else {-
167 return QApplication::desktop()->availableGeometry(screen);-
168 }-
169}-
170-
171QVector<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const-
172{-
173 QVector<QPointer<QWidget> > ret;-
174 for(QWidget *widget = causedPopup.widget; widget; ) {-
175 ret.append(widget);-
176 if (QTornOffMenu *qtmenu = qobject_cast<QTornOffMenu*>(widget))-
177 ret += qtmenu->d_func()->causedStack;-
178 if (QMenu *qmenu = qobject_cast<QMenu*>(widget))-
179 widget = qmenu->d_func()->causedPopup.widget;-
180 else-
181 break;-
182 }-
183 return ret;-
184}-
185-
186void QMenuPrivate::updateActionRects() const-
187{-
188 const QMenu * const q = q_func();-
189 updateActionRects(popupGeometry(q));-
190}-
191-
192void QMenuPrivate::updateActionRects(const QRect &screen) const-
193{-
194 const QMenu * const q = q_func();-
195 if (!itemsDirty)-
196 return;-
197-
198 q->ensurePolished();-
199-
200-
201 actionRects.resize(actions.count());-
202 actionRects.fill(QRect());-
203-
204 int lastVisibleAction = getLastVisibleAction();-
205-
206 int max_column_width = 0,-
207 dh = screen.height(),-
208 y = 0;-
209 QStyle *style = q->style();-
210 QStyleOption opt;-
211 opt.init(q);-
212 const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, &opt, q),-
213 vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, &opt, q),-
214 icone = style->pixelMetric(QStyle::PM_SmallIconSize, &opt, q);-
215 const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, q);-
216 const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q);-
217 const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0;-
218-
219-
220 tabWidth = 0;-
221 maxIconWidth = 0;-
222 hasCheckableItems = false;-
223 ncols = 1;-
224-
225 for (int i = 0; i < actions.count(); ++i) {-
226 QAction *action = actions.at(i);-
227 if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action))-
228 continue;-
229-
230 hasCheckableItems |= action->isCheckable();-
231 QIcon is = action->icon();-
232 if (!is.isNull()) {-
233 maxIconWidth = qMax<uint>(maxIconWidth, icone + 4);-
234 }-
235 }-
236-
237-
238 QFontMetrics qfm = q->fontMetrics();-
239 bool previousWasSeparator = true;-
240 for(int i = 0; i <= lastVisibleAction; i++) {-
241 QAction *action = actions.at(i);-
242 const bool isSection = action->isSeparator() && (!action->text().isEmpty() || !action->icon().isNull());-
243 const bool isPlainSeparator = (isSection && !q->style()->styleHint(QStyle::SH_Menu_SupportsSections))-
244 || (action->isSeparator() && !isSection);-
245-
246 if (!action->isVisible() ||-
247 (collapsibleSeparators && previousWasSeparator && isPlainSeparator))-
248 continue;-
249-
250 previousWasSeparator = isPlainSeparator;-
251-
252-
253 QStyleOptionMenuItem opt;-
254 q->initStyleOption(&opt, action);-
255 const QFontMetrics &fm = opt.fontMetrics;-
256-
257 QSize sz;-
258 if (QWidget *w = widgetItems.value(action)) {-
259 sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize());-
260 } else {-
261-
262 if (action->isSeparator()) {-
263 sz = QSize(2, 2);-
264 } else {-
265 QString s = action->text();-
266 int t = s.indexOf(QLatin1Char('\t'));-
267 if (t != -1) {-
268 tabWidth = qMax(int(tabWidth), qfm.width(s.mid(t+1)));-
269 s = s.left(t);-
270-
271 } else {-
272 QKeySequence seq = action->shortcut();-
273 if (!seq.isEmpty())-
274 tabWidth = qMax(int(tabWidth), qfm.width(seq.toString(QKeySequence::NativeText)));-
275-
276 }-
277 sz.setWidth(fm.boundingRect(QRect(), Qt::TextSingleLine | Qt::TextShowMnemonic, s).width());-
278 sz.setHeight(qMax(fm.height(), qfm.height()));-
279-
280 QIcon is = action->icon();-
281 if (!is.isNull()) {-
282 QSize is_sz = QSize(icone, icone);-
283 if (is_sz.height() > sz.height())-
284 sz.setHeight(is_sz.height());-
285 }-
286 }-
287 sz = style->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, q);-
288 }-
289-
290-
291 if (!sz.isEmpty()) {-
292 max_column_width = qMax(max_column_width, sz.width());-
293-
294 if (!scroll &&-
295 y+sz.height()+vmargin > dh - (deskFw * 2)) {-
296 ncols++;-
297 y = vmargin;-
298 }-
299 y += sz.height();-
300-
301 actionRects[i] = QRect(0, 0, sz.width(), sz.height());-
302 }-
303 }-
304-
305 max_column_width += tabWidth;-
306 const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width();-
307 const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin));-
308 max_column_width = qMax(min_column_width, max_column_width);-
309-
310-
311 const int base_y = vmargin + fw + topmargin +-
312 (scroll ? scroll->scrollOffset : 0) +-
313 tearoffHeight;-
314 int x = hmargin + fw + leftmargin;-
315 y = base_y;-
316-
317 for(int i = 0; i < actions.count(); i++) {-
318 QRect &rect = actionRects[i];-
319 if (rect.isNull())-
320 continue;-
321 if (!scroll &&-
322 y+rect.height() > dh - deskFw * 2) {-
323 x += max_column_width + hmargin;-
324 y = base_y;-
325 }-
326 rect.translate(x, y);-
327 rect.setWidth(max_column_width);-
328-
329-
330 if (QWidget *widget = widgetItems.value(actions.at(i))) {-
331 widget->setGeometry(rect);-
332 widget->setVisible(actions.at(i)->isVisible());-
333 }-
334-
335 y += rect.height();-
336 }-
337 itemsDirty = 0;-
338}-
339-
340QSize QMenuPrivate::adjustMenuSizeForScreen(const QRect &screen)-
341{-
342 QMenu * const q = q_func();-
343 QSize ret = screen.size();-
344 itemsDirty = true;-
345 updateActionRects(screen);-
346 const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);-
347 ret.setWidth(actionRects.at(getLastVisibleAction()).right() + fw);-
348 return ret;-
349}-
350-
351int QMenuPrivate::getLastVisibleAction() const-
352{-
353-
354 int lastVisibleAction = actions.count() - 1;-
355 for (;lastVisibleAction >= 0; --lastVisibleAction) {-
356 const QAction *action = actions.at(lastVisibleAction);-
357 if (action->isVisible()) {-
358-
359 if (action->isSeparator() && collapsibleSeparators)-
360 continue;-
361 break;-
362 }-
363 }-
364 return lastVisibleAction;-
365}-
366-
367-
368QRect QMenuPrivate::actionRect(QAction *act) const-
369{-
370 int index = actions.indexOf(act);-
371 if (index == -1)-
372 return QRect();-
373-
374 updateActionRects();-
375-
376-
377 return actionRects.at(index);-
378}-
379-
380void QMenuPrivate::hideUpToMenuBar()-
381{-
382 QMenu * const q = q_func();-
383 bool fadeMenus = q->style()->styleHint(QStyle::SH_Menu_FadeOutOnHide);-
384 if (!tornoff) {-
385 QWidget *caused = causedPopup.widget;-
386 hideMenu(q);-
387 while(caused) {-
388-
389 if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {-
390 mb->d_func()->setCurrentAction(0);-
391 mb->d_func()->setKeyboardMode(false);-
392 caused = 0;-
393 } else-
394-
395 if (QMenu *m = qobject_cast<QMenu*>(caused)) {-
396 caused = m->d_func()->causedPopup.widget;-
397 if (!m->d_func()->tornoff)-
398 hideMenu(m);-
399 if (!fadeMenus)-
400 m->d_func()->setCurrentAction(0);-
401 } else { caused = 0;-
402 }-
403 }-
404 }-
405 setCurrentAction(0);-
406}-
407-
408void QMenuPrivate::hideMenu(QMenu *menu)-
409{-
410 if (!menu)-
411 return;-
412-
413 QSignalBlocker blocker(menu);-
414 aboutToHide = true;-
415-
416 if (menu->style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)-
417 && currentAction && currentAction == actionAboutToTrigger-
418 && menu->actions().contains(currentAction)) {-
419 QEventLoop eventLoop;-
420 QAction *activeAction = currentAction;-
421-
422 menu->setActiveAction(0);-
423 QTimer::singleShot(60, &eventLoop, qFlagLocation("1""quit()" "\0" __FILE__ ":" "474""480"));-
424 eventLoop.exec();-
425-
426-
427 menu->setActiveAction(activeAction);-
428 QTimer::singleShot(20, &eventLoop, qFlagLocation("1""quit()" "\0" __FILE__ ":" "479""485"));-
429 eventLoop.exec();-
430 }-
431-
432 aboutToHide = false;-
433 blocker.unblock();-
434-
435 if (activeMenu == menu)-
436 activeMenu = 0;-
437 menu->d_func()->causedPopup.action = 0;-
438 menu->close();-
439 menu->d_func()->causedPopup.widget = 0;-
440}-
441-
442void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst)-
443{-
444 QMenu * const q = q_func();-
445 if (action) {-
446 if (action->isEnabled()) {-
447 if (!delay)-
448 q->internalDelayedPopup();-
449 else if (action->menu() && !action->menu()->isVisible())-
450 delayState.start(delay, action);-
451 else if (!action->menu())-
452 delayState.stop();-
453 if (activateFirst && action->menu())-
454 action->menu()->d_func()->setFirstActionActive();-
455 }-
456 } else if (QMenu *menu = activeMenu) {-
457 hideMenu(menu);-
458 }-
459}-
460-
461void QMenuPrivate::setSyncAction()-
462{-
463 QMenu * const q = q_func();-
464 QAction *current = currentAction;-
465 if(current && (!current->isEnabled() || current->menu() || current->isSeparator()))-
466 current = 0;-
467 for(QWidget *caused = q; caused;) {-
468 if (QMenu *m = qobject_cast<QMenu*>(caused)) {-
469 caused = m->d_func()->causedPopup.widget;-
470 if (m->d_func()->eventLoop)-
471 m->d_func()->syncAction = current;-
472 } else {-
473 break;-
474 }-
475 }-
476}-
477-
478-
479void QMenuPrivate::setFirstActionActive()-
480{-
481 QMenu * const q = q_func();-
482 updateActionRects();-
483 for(int i = 0, saccum = 0; i < actions.count(); i++) {-
484 const QRect &rect = actionRects.at(i);-
485 if (rect.isNull())-
486 continue;-
487 if (scroll && scroll->scrollFlags & QMenuScroller::ScrollUp) {-
488 saccum -= rect.height();-
489 if (saccum > scroll->scrollOffset - scrollerHeight())-
490 continue;-
491 }-
492 QAction *act = actions.at(i);-
493 if (!act->isSeparator() &&-
494 (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)-
495 || act->isEnabled())) {-
496 setCurrentAction(act);-
497 break;-
498 }-
499 }-
500}-
501-
502-
503void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason reason, bool activateFirst)-
504{-
505 QMenu * const q = q_func();-
506 tearoffHighlighted = 0;-
507-
508 if (action-
509 && (action->isSeparator()-
510 || (!action->isEnabled() && !q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q))))-
511 action = nullptr;-
512-
513-
514-
515 if (reason != SelectedFromKeyboard) {-
516 if (QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) {-
517 if (causedPopup.action && menu->d_func()->activeMenu == q)-
518-
519 if (hasReceievedEnter && menu->d_func()->currentAction != causedPopup.action)-
520 menu->d_func()->setCurrentAction(causedPopup.action, 0, reason, false);-
521 }-
522 }-
523-
524 if (currentAction)-
525 q->update(actionRect(currentAction));-
526-
527 QMenu *hideActiveMenu = activeMenu;-
528 QAction *previousAction = currentAction;-
529-
530 currentAction = action;-
531 if (action) {-
532 if (!action->isSeparator()) {-
533 activateAction(action, QAction::Hover);-
534 if (popup != -1) {-
535-
536-
537-
538 if (q->isVisible())-
539 popupAction(currentAction, popup, activateFirst);-
540 }-
541 q->update(actionRect(action));-
542-
543 if (reason == SelectedFromKeyboard) {-
544 QWidget *widget = widgetItems.value(action);-
545 if (widget) {-
546 if (widget->focusPolicy() != Qt::NoFocus)-
547 widget->setFocus(Qt::TabFocusReason);-
548 } else {-
549-
550-
551-
552 if (!q->hasFocus()) {-
553 q->setFocus(Qt::PopupFocusReason);-
554 }-
555 }-
556 }-
557 }-
558-
559 } else if (previousAction) {-
560 previousAction->d_func()->showStatusText(topCausedWidget(), QString());-
561-
562 }-
563 if (hideActiveMenu && previousAction != currentAction) {-
564 if (popup == -1) {-
565-
566-
567 qFadeEffect(0);-
568 qScrollEffect(0);-
569-
570 hideMenu(hideActiveMenu);-
571 } else if (!currentAction || !currentAction->menu()) {-
572 sloppyState.startTimerIfNotRunning();-
573 }-
574 }-
575}-
576-
577void QMenuSloppyState::reset()-
578{-
579 m_enabled = false;-
580 m_first_mouse = true;-
581 m_init_guard = false;-
582 m_uni_dir_discarded_count = 0;-
583 m_time.stop();-
584 m_reset_action = nullptr;-
585 m_origin_action = nullptr;-
586 m_action_rect = QRect();-
587 m_previous_point = QPointF();-
588 if (m_sub_menu) {-
589 QMenuPrivate::get(m_sub_menu)->sloppyState.m_parent = nullptr;-
590 m_sub_menu = nullptr;-
591 }-
592}-
593void QMenuSloppyState::enter()-
594{-
595 QMenuPrivate *menuPriv = QMenuPrivate::get(m_menu);-
596-
597 if (m_discard_state_when_entering_parent && m_sub_menu == menuPriv->activeMenu) {-
598 menuPriv->hideMenu(m_sub_menu);-
599 reset();-
600 }-
601 if (m_parent)-
602 m_parent->childEnter();-
603}-
604-
605void QMenuSloppyState::childEnter()-
606{-
607 stopTimer();-
608 if (m_parent)-
609 m_parent->childEnter();-
610}-
611-
612void QMenuSloppyState::leave()-
613{-
614 if (!m_dont_start_time_on_leave) {-
615 if (m_parent)-
616 m_parent->childLeave();-
617 startTimerIfNotRunning();-
618 }-
619}-
620-
621void QMenuSloppyState::childLeave()-
622{-
623 if (m_enabled && !QMenuPrivate::get(m_menu)->hasReceievedEnter) {-
624 startTimerIfNotRunning();-
625 if (m_parent)-
626 m_parent->childLeave();-
627 }-
628}-
629-
630void QMenuSloppyState::setSubMenuPopup(const QRect &actionRect, QAction *resetAction, QMenu *subMenu)-
631{-
632 m_enabled = true;-
633 m_init_guard = true;-
634 m_time.stop();-
635 m_action_rect = actionRect;-
636 m_sub_menu = subMenu;-
637 QMenuPrivate::get(subMenu)->sloppyState.m_parent = this;-
638 m_reset_action = resetAction;-
639 m_origin_action = resetAction;-
640}-
641-
642bool QMenuSloppyState::hasParentActiveDelayTimer() const-
643{-
644 return m_parent && m_parent->m_menu && QMenuPrivate::get(m_parent->m_menu)->delayState.timer.isActive();-
645}-
646-
647class ResetOnDestroy-
648{-
649public:-
650 ResetOnDestroy(QMenuSloppyState *sloppyState, bool *guard)-
651 : toReset(sloppyState)-
652 , guard(guard)-
653 {-
654 *guard = false;-
655 }-
656-
657 ~ResetOnDestroy()-
658 {-
659 if (!*guard)-
660 toReset->reset();-
661 }-
662-
663 QMenuSloppyState *toReset;-
664 bool *guard;-
665};-
666-
667void QMenuSloppyState::timeout()-
668{-
669 QMenuPrivate *menu_priv = QMenuPrivate::get(m_menu);-
670-
671 bool reallyHasMouse = menu_priv->hasReceievedEnter;-
672 if (!reallyHasMouse) {-
673-
674-
675 const QPoint lastCursorPos = QGuiApplicationPrivate::lastCursorPosition.toPoint();-
676 reallyHasMouse = m_menu->frameGeometry().contains(lastCursorPos);-
677 }-
678-
679 if (menu_priv->currentAction == m_reset_action-
680 && reallyHasMouse-
681 && (menu_priv->currentAction-
682 && menu_priv->currentAction->menu() == menu_priv->activeMenu)) {-
683 return;-
684 }-
685-
686 ResetOnDestroy resetState(this, &m_init_guard);-
687-
688 if (hasParentActiveDelayTimer() || !m_menu->isVisible())-
689 return;-
690-
691 if (m_sub_menu)-
692 menu_priv->hideMenu(m_sub_menu);-
693-
694 if (reallyHasMouse)-
695 menu_priv->setCurrentAction(m_reset_action,0);-
696 else-
697 menu_priv->setCurrentAction(nullptr, 0);-
698}-
699-
700-
701QWidget *QMenuPrivate::topCausedWidget() const-
702{-
703 QWidget* top = causedPopup.widget;-
704 while (QMenu* m = qobject_cast<QMenu *>(top))-
705 top = m->d_func()->causedPopup.widget;-
706 return top;-
707}-
708-
709QAction *QMenuPrivate::actionAt(QPoint p) const-
710{-
711 if (!q_func()->rect().contains(p))-
712 return 0;-
713-
714 for(int i = 0; i < actionRects.count(); i++) {-
715 if (actionRects.at(i).contains(p))-
716 return actions.at(i);-
717 }-
718 return 0;-
719}-
720-
721void QMenuPrivate::setOverrideMenuAction(QAction *a)-
722{-
723 QMenu * const q = q_func();-
724 QObject::disconnect(menuAction, qFlagLocation("2""destroyed()" "\0" __FILE__ ":" "775""781"), q, qFlagLocation("1""_q_overrideMenuActionDestroyed()" "\0" __FILE__ ":" "775""781"));-
725 if (a) {-
726 menuAction = a;-
727 QObject::connect(a, qFlagLocation("2""destroyed()" "\0" __FILE__ ":" "778""784"), q, qFlagLocation("1""_q_overrideMenuActionDestroyed()" "\0" __FILE__ ":" "778""784"));-
728 } else {-
729 menuAction = defaultMenuAction;-
730 }-
731}-
732-
733void QMenuPrivate::_q_overrideMenuActionDestroyed()-
734{-
735 menuAction=defaultMenuAction;-
736}-
737-
738-
739void QMenuPrivate::updateLayoutDirection()-
740{-
741 QMenu * const q = q_func();-
742-
743-
744-
745 if (!q->testAttribute(Qt::WA_SetLayoutDirection)) {-
746 if (QWidget *w = causedPopup.widget)-
747 setLayoutDirection_helper(w->layoutDirection());-
748 else if (QWidget *w = q->parentWidget())-
749 setLayoutDirection_helper(w->layoutDirection());-
750 else-
751 setLayoutDirection_helper(QApplication::layoutDirection());-
752 }-
753}-
754-
755-
756-
757-
758-
759QAction *QMenu::menuAction() const-
760{-
761 return d_func()->menuAction;-
762}-
763QString QMenu::title() const-
764{-
765 return d_func()->menuAction->text();-
766}-
767-
768void QMenu::setTitle(const QString &text)-
769{-
770 d_func()->menuAction->setText(text);-
771}-
772QIcon QMenu::icon() const-
773{-
774 return d_func()->menuAction->icon();-
775}-
776-
777void QMenu::setIcon(const QIcon &icon)-
778{-
779 d_func()->menuAction->setIcon(icon);-
780}-
781-
782-
783-
784void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active)-
785{-
786 QMenu * const q = q_func();-
787 if (!scroll || !scroll->scrollFlags)-
788 return;-
789 updateActionRects();-
790 int newOffset = 0;-
791 const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;-
792 const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;-
793 const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);-
794 const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);-
795-
796 if (location == QMenuScroller::ScrollTop) {-
797 for(int i = 0, saccum = 0; i < actions.count(); i++) {-
798 if (actions.at(i) == action) {-
799 newOffset = topScroll - saccum;-
800 break;-
801 }-
802 saccum += actionRects.at(i).height();-
803 }-
804 } else {-
805 for(int i = 0, saccum = 0; i < actions.count(); i++) {-
806 saccum += actionRects.at(i).height();-
807 if (actions.at(i) == action) {-
808 if (location == QMenuScroller::ScrollCenter)-
809 newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll);-
810 else-
811 newOffset = (q->height() - botScroll) - saccum;-
812 break;-
813 }-
814 }-
815 if(newOffset)-
816 newOffset -= fw * 2;-
817 }-
818-
819-
820 uint newScrollFlags = QMenuScroller::ScrollNone;-
821 if (newOffset < 0)-
822 newScrollFlags |= QMenuScroller::ScrollUp;-
823 int saccum = newOffset;-
824 for(int i = 0; i < actionRects.count(); i++) {-
825 saccum += actionRects.at(i).height();-
826 if (saccum > q->height()) {-
827 newScrollFlags |= QMenuScroller::ScrollDown;-
828 break;-
829 }-
830 }-
831-
832 if (!(newScrollFlags & QMenuScroller::ScrollDown) && (scroll->scrollFlags & QMenuScroller::ScrollDown)) {-
833 newOffset = q->height() - (saccum - newOffset) - fw*2 - vmargin;-
834 }-
835-
836 if (!(newScrollFlags & QMenuScroller::ScrollUp) && (scroll->scrollFlags & QMenuScroller::ScrollUp)) {-
837 newOffset = 0;-
838 }-
839-
840 if (newScrollFlags & QMenuScroller::ScrollUp)-
841 newOffset -= vmargin;-
842-
843 QRect screen = popupGeometry(q);-
844 const int desktopFrame = q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q);-
845 if (q->height() < screen.height()-(desktopFrame*2)-1) {-
846 QRect geom = q->geometry();-
847 if (newOffset > scroll->scrollOffset && (scroll->scrollFlags & newScrollFlags & QMenuScroller::ScrollUp)) {-
848 const int newHeight = geom.height()-(newOffset-scroll->scrollOffset);-
849 if(newHeight > geom.height())-
850 geom.setHeight(newHeight);-
851 } else if(scroll->scrollFlags & newScrollFlags & QMenuScroller::ScrollDown) {-
852 int newTop = geom.top() + (newOffset-scroll->scrollOffset);-
853 if (newTop < desktopFrame+screen.top())-
854 newTop = desktopFrame+screen.top();-
855 if (newTop < geom.top()) {-
856 geom.setTop(newTop);-
857 newOffset = 0;-
858 newScrollFlags &= ~QMenuScroller::ScrollUp;-
859 }-
860 }-
861 if (geom.bottom() > screen.bottom() - desktopFrame)-
862 geom.setBottom(screen.bottom() - desktopFrame);-
863 if (geom.top() < desktopFrame+screen.top())-
864 geom.setTop(desktopFrame+screen.top());-
865 if (geom != q->geometry()) {-
866-
867-
868-
869-
870-
871 q->setGeometry(geom);-
872 }-
873 }-
874-
875-
876 const int delta = qMin(0, newOffset) - scroll->scrollOffset;-
877 if (!itemsDirty && delta) {-
878-
879 for (int i = 0; i < actionRects.count(); ++i) {-
880 QRect &current = actionRects[i];-
881 current.moveTop(current.top() + delta);-
882-
883-
884 if (QWidget *w = widgetItems.value(actions.at(i)))-
885 w->setGeometry(current);-
886 }-
887 }-
888 scroll->scrollOffset += delta;-
889 scroll->scrollFlags = newScrollFlags;-
890 if (active)-
891 setCurrentAction(action);-
892-
893 q->update();-
894}-
895-
896void QMenuPrivate::scrollMenu(QMenuScroller::ScrollLocation location, bool active)-
897{-
898 QMenu * const q = q_func();-
899 updateActionRects();-
900 if(location == QMenuScroller::ScrollBottom) {-
901 for(int i = actions.size()-1; i >= 0; --i) {-
902 QAction *act = actions.at(i);-
903 if (actionRects.at(i).isNull())-
904 continue;-
905 if (!act->isSeparator() &&-
906 (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)-
907 || act->isEnabled())) {-
908 if(scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)-
909 scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollBottom, active);-
910 else if(active)-
911 setCurrentAction(act, -1, QMenuPrivate::SelectedFromKeyboard);-
912 break;-
913 }-
914 }-
915 } else if(location == QMenuScroller::ScrollTop) {-
916 for(int i = 0; i < actions.size(); ++i) {-
917 QAction *act = actions.at(i);-
918 if (actionRects.at(i).isNull())-
919 continue;-
920 if (!act->isSeparator() &&-
921 (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)-
922 || act->isEnabled())) {-
923 if(scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)-
924 scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollTop, active);-
925 else if(active)-
926 setCurrentAction(act, -1, QMenuPrivate::SelectedFromKeyboard);-
927 break;-
928 }-
929 }-
930 }-
931}-
932-
933-
934void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool page, bool active)-
935{-
936 QMenu * const q = q_func();-
937 if (!scroll || !(scroll->scrollFlags & direction))-
938 return;-
939 updateActionRects();-
940 const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;-
941 const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;-
942 const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);-
943 const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);-
944 const int offset = topScroll ? topScroll-vmargin : 0;-
945 if (direction == QMenuScroller::ScrollUp) {-
946 for(int i = 0, saccum = 0; i < actions.count(); i++) {-
947 saccum -= actionRects.at(i).height();-
948 if (saccum <= scroll->scrollOffset-offset) {-
949 scrollMenu(actions.at(i), page ? QMenuScroller::ScrollBottom : QMenuScroller::ScrollTop, active);-
950 break;-
951 }-
952 }-
953 } else if (direction == QMenuScroller::ScrollDown) {-
954 bool scrolled = false;-
955 for(int i = 0, saccum = 0; i < actions.count(); i++) {-
956 const int iHeight = actionRects.at(i).height();-
957 saccum -= iHeight;-
958 if (saccum <= scroll->scrollOffset-offset) {-
959 const int scrollerArea = q->height() - botScroll - fw*2;-
960 int visible = (scroll->scrollOffset-offset) - saccum;-
961 for(i++ ; i < actions.count(); i++) {-
962 visible += actionRects.at(i).height();-
963 if (visible > scrollerArea - topScroll) {-
964 scrolled = true;-
965 scrollMenu(actions.at(i), page ? QMenuScroller::ScrollTop : QMenuScroller::ScrollBottom, active);-
966 break;-
967 }-
968 }-
969 break;-
970 }-
971 }-
972 if(!scrolled) {-
973 scroll->scrollFlags &= ~QMenuScroller::ScrollDown;-
974 q->update();-
975 }-
976 }-
977}-
978-
979-
980-
981bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)-
982{-
983 QMenu * const q = q_func();-
984 QPoint pos = q->mapFromGlobal(e->globalPos());-
985 if (scroll && !activeMenu) {-
986 bool isScroll = false;-
987 if (pos.x() >= 0 && pos.x() < q->width()) {-
988 for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) {-
989 if (scroll->scrollFlags & dir) {-
990 if (dir == QMenuScroller::ScrollUp)-
991 isScroll = (pos.y() <= scrollerHeight());-
992 else if (dir == QMenuScroller::ScrollDown)-
993 isScroll = (pos.y() >= q->height() - scrollerHeight());-
994 if (isScroll) {-
995 scroll->scrollDirection = dir;-
996 break;-
997 }-
998 }-
999 }-
1000 }-
1001 if (isScroll) {-
1002 scroll->scrollTimer.start(50, q);-
1003 return true;-
1004 } else {-
1005 scroll->scrollTimer.stop();-
1006 }-
1007 }-
1008-
1009 if (tearoff) {-
1010 QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q));-
1011 if (scroll && scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)-
1012 tearRect.translate(0, scrollerHeight());-
1013 q->update(tearRect);-
1014 if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) {-
1015 setCurrentAction(0);-
1016 tearoffHighlighted = 1;-
1017 if (e->type() == QEvent::MouseButtonRelease) {-
1018 if (!tornPopup)-
1019 tornPopup = new QTornOffMenu(q);-
1020 tornPopup->setGeometry(q->geometry());-
1021 tornPopup->show();-
1022 hideUpToMenuBar();-
1023 }-
1024 return true;-
1025 }-
1026 tearoffHighlighted = 0;-
1027 }-
1028-
1029 if (q->frameGeometry().contains(e->globalPos()))-
1030 return false;-
1031-
1032 for(QWidget *caused = causedPopup.widget; caused;) {-
1033 bool passOnEvent = false;-
1034 QWidget *next_widget = 0;-
1035 QPoint cpos = caused->mapFromGlobal(e->globalPos());-
1036-
1037 if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {-
1038 passOnEvent = mb->rect().contains(cpos);-
1039 } else-
1040-
1041 if (QMenu *m = qobject_cast<QMenu*>(caused)) {-
1042 passOnEvent = m->rect().contains(cpos);-
1043 next_widget = m->d_func()->causedPopup.widget;-
1044 }-
1045 if (passOnEvent) {-
1046 if (e->type() != QEvent::MouseButtonRelease || mouseDown == caused) {-
1047 QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(),-
1048 e->button(), e->buttons(), e->modifiers(), e->source());-
1049 QApplication::sendEvent(caused, &new_e);-
1050 return true;-
1051 }-
1052 }-
1053 caused = next_widget;-
1054 if (!caused)-
1055 sloppyState.leave();-
1056 }-
1057 return false;-
1058}-
1059-
1060void QMenuPrivate::activateCausedStack(const QVector<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self)-
1061{-
1062 QBoolBlocker guard(activationRecursionGuard);-
1063 if(self)-
1064 action->activate(action_e);-
1065-
1066 for(int i = 0; i < causedStack.size(); ++i) {-
1067 QPointer<QWidget> widget = causedStack.at(i);-
1068 if (!widget)-
1069 continue;-
1070-
1071 if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {-
1072 widget = qmenu->d_func()->causedPopup.widget;-
1073 if (action_e == QAction::Trigger) {-
1074 qmenu->triggered(action);-
1075 } else if (action_e == QAction::Hover) {-
1076 qmenu->hovered(action);-
1077 }-
1078-
1079 } else if (QMenuBar *qmenubar = qobject_cast<QMenuBar*>(widget)) {-
1080 if (action_e == QAction::Trigger) {-
1081 qmenubar->triggered(action);-
1082 } else if (action_e == QAction::Hover) {-
1083 qmenubar->hovered(action);-
1084 }-
1085 break;-
1086-
1087 }-
1088 }-
1089}-
1090-
1091void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e, bool self)-
1092{-
1093 QMenu * const q = q_func();-
1094-
1095 bool inWhatsThisMode = QWhatsThis::inWhatsThisMode();-
1096-
1097 if (!action || !q->isEnabled()-
1098 || (action_e == QAction::Trigger-
1099-
1100 && !inWhatsThisMode-
1101-
1102 && (action->isSeparator() ||!action->isEnabled())))-
1103 return;-
1104-
1105-
1106-
1107-
1108 const QVector<QPointer<QWidget> > causedStack = calcCausedStack();-
1109 if (action_e == QAction::Trigger) {-
1110-
1111 if (!inWhatsThisMode)-
1112 actionAboutToTrigger = action;-
1113-
1114-
1115 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {-
1116 hideUpToMenuBar();-
1117 } else {-
1118 for(QWidget *widget = QApplication::activePopupWidget(); widget; ) {-
1119 if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {-
1120 if(qmenu == q)-
1121 hideUpToMenuBar();-
1122 widget = qmenu->d_func()->causedPopup.widget;-
1123 } else {-
1124 break;-
1125 }-
1126 }-
1127 }-
1128-
1129-
1130 if (inWhatsThisMode) {-
1131 QString s = action->whatsThis();-
1132 if (s.isEmpty())-
1133 s = whatsThis;-
1134 QWhatsThis::showText(q->mapToGlobal(actionRect(action).center()), s, q);-
1135 return;-
1136 }-
1137-
1138 }-
1139-
1140-
1141 activateCausedStack(causedStack, action, action_e, self);-
1142-
1143-
1144 if (action_e == QAction::Hover) {-
1145-
1146 if (QAccessible::isActive()) {-
1147 int actionIndex = indexOf(action);-
1148 QAccessibleEvent focusEvent(q, QAccessible::Focus);-
1149 focusEvent.setChild(actionIndex);-
1150 QAccessible::updateAccessibility(&focusEvent);-
1151 }-
1152-
1153 action->showStatusText(topCausedWidget());-
1154 } else {-
1155 actionAboutToTrigger = 0;-
1156 }-
1157}-
1158-
1159void QMenuPrivate::_q_actionTriggered()-
1160{-
1161 QMenu * const q = q_func();-
1162 if (QAction *action = qobject_cast<QAction *>(q->sender())) {-
1163 QPointer<QAction> actionGuard = action;-
1164 if (platformMenu && widgetItems.value(action))-
1165 platformMenu->dismiss();-
1166 q->triggered(action);-
1167 if (!activationRecursionGuard && actionGuard) {-
1168-
1169-
1170 QVector< QPointer<QWidget> > list;-
1171 for(QWidget *widget = q->parentWidget(); widget; ) {-
1172 if (qobject_cast<QMenu*>(widget)-
1173-
1174 || qobject_cast<QMenuBar*>(widget)-
1175-
1176 ) {-
1177 list.append(widget);-
1178 widget = widget->parentWidget();-
1179 } else {-
1180 break;-
1181 }-
1182 }-
1183 activateCausedStack(list, action, QAction::Trigger, false);-
1184 }-
1185 }-
1186}-
1187-
1188void QMenuPrivate::_q_actionHovered()-
1189{-
1190 QMenu * const q = q_func();-
1191 if (QAction * action = qobject_cast<QAction *>(q->sender())) {-
1192 q->hovered(action);-
1193 }-
1194}-
1195-
1196void QMenuPrivate::_q_platformMenuAboutToShow()-
1197{-
1198 QMenu * const q = q_func();-
1199 q->aboutToShow();-
1200}
never executed: end of block
0
1201-
1202bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)-
1203{-
1204-
1205-
1206-
1207 return motions > 6 ||-
1208 QApplication::startDragDistance() < (mousePopupPos - globalPos).manhattanLength();-
1209}-
1210void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const-
1211{-
1212 if (!option || !action)-
1213 return;-
1214-
1215 const QMenuPrivate * const d = d_func();-
1216 option->initFrom(this);-
1217 option->palette = palette();-
1218 option->state = QStyle::State_None;-
1219-
1220 if (window()->isActiveWindow())-
1221 option->state |= QStyle::State_Active;-
1222 if (isEnabled() && action->isEnabled()-
1223 && (!action->menu() || action->menu()->isEnabled()))-
1224 option->state |= QStyle::State_Enabled;-
1225 else-
1226 option->palette.setCurrentColorGroup(QPalette::Disabled);-
1227-
1228 option->font = action->font().resolve(font());-
1229 option->fontMetrics = QFontMetrics(option->font);-
1230-
1231 if (d->currentAction && d->currentAction == action && !d->currentAction->isSeparator()) {-
1232 option->state |= QStyle::State_Selected-
1233 | (d->mouseDown ? QStyle::State_Sunken : QStyle::State_None);-
1234 }-
1235-
1236 option->menuHasCheckableItems = d->hasCheckableItems;-
1237 if (!action->isCheckable()) {-
1238 option->checkType = QStyleOptionMenuItem::NotCheckable;-
1239 } else {-
1240 option->checkType = (action->actionGroup() && action->actionGroup()->isExclusive())-
1241 ? QStyleOptionMenuItem::Exclusive : QStyleOptionMenuItem::NonExclusive;-
1242 option->checked = action->isChecked();-
1243 }-
1244 if (action->menu())-
1245 option->menuItemType = QStyleOptionMenuItem::SubMenu;-
1246 else if (action->isSeparator())-
1247 option->menuItemType = QStyleOptionMenuItem::Separator;-
1248 else if (d->defaultAction == action)-
1249 option->menuItemType = QStyleOptionMenuItem::DefaultItem;-
1250 else-
1251 option->menuItemType = QStyleOptionMenuItem::Normal;-
1252 if (action->isIconVisibleInMenu())-
1253 option->icon = action->icon();-
1254 QString textAndAccel = action->text();-
1255-
1256 if (textAndAccel.indexOf(QLatin1Char('\t')) == -1) {-
1257 QKeySequence seq = action->shortcut();-
1258 if (!seq.isEmpty())-
1259 textAndAccel += QLatin1Char('\t') + seq.toString(QKeySequence::NativeText);-
1260 }-
1261-
1262 option->text = textAndAccel;-
1263 option->tabWidth = d->tabWidth;-
1264 option->maxIconWidth = d->maxIconWidth;-
1265 option->menuRect = rect();-
1266}-
1267QMenu::QMenu(QWidget *parent)-
1268 : QWidget(*new QMenuPrivate, parent, Qt::Popup)-
1269{-
1270 QMenuPrivate * const d = d_func();-
1271 d->init();-
1272}-
1273QMenu::QMenu(const QString &title, QWidget *parent)-
1274 : QWidget(*new QMenuPrivate, parent, Qt::Popup)-
1275{-
1276 QMenuPrivate * const d = d_func();-
1277 d->init();-
1278 d->menuAction->setText(title);-
1279}-
1280-
1281-
1282-
1283QMenu::QMenu(QMenuPrivate &dd, QWidget *parent)-
1284 : QWidget(dd, parent, Qt::Popup)-
1285{-
1286 QMenuPrivate * const d = d_func();-
1287 d->init();-
1288}-
1289-
1290-
1291-
1292-
1293QMenu::~QMenu()-
1294{-
1295 QMenuPrivate * const d = d_func();-
1296 if (!d->widgetItems.isEmpty()) {-
1297 QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin();-
1298 for (; it != d->widgetItems.end(); ++it) {-
1299 if (QWidget *widget = it.value()) {-
1300 QWidgetAction *action = static_cast<QWidgetAction *>(it.key());-
1301 action->releaseWidget(widget);-
1302 *it = 0;-
1303 }-
1304 }-
1305 }-
1306-
1307 if (d->eventLoop)-
1308 d->eventLoop->exit();-
1309 hideTearOffMenu();-
1310}-
1311QAction *QMenu::addAction(const QString &text)-
1312{-
1313 QAction *ret = new QAction(text, this);-
1314 addAction(ret);-
1315 return ret;-
1316}-
1317QAction *QMenu::addAction(const QIcon &icon, const QString &text)-
1318{-
1319 QAction *ret = new QAction(icon, text, this);-
1320 addAction(ret);-
1321 return ret;-
1322}-
1323QAction *QMenu::addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut)-
1324{-
1325 QAction *action = new QAction(text, this);-
1326-
1327-
1328-
1329 action->setShortcut(shortcut);-
1330-
1331 QObject::connect(action, qFlagLocation("2""triggered(bool)" "\0" __FILE__ ":" "1574""1577"), receiver, member);-
1332 addAction(action);-
1333 return action;-
1334}-
1335QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver,-
1336 const char* member, const QKeySequence &shortcut)-
1337{-
1338 QAction *action = new QAction(icon, text, this);-
1339-
1340-
1341-
1342 action->setShortcut(shortcut);-
1343-
1344 QObject::connect(action, qFlagLocation("2""triggered(bool)" "\0" __FILE__ ":" "1695""1698"), receiver, member);-
1345 addAction(action);-
1346 return action;-
1347}-
1348QAction *QMenu::addMenu(QMenu *menu)-
1349{-
1350 QAction *action = menu->menuAction();-
1351 addAction(action);-
1352 return action;-
1353}-
1354-
1355-
1356-
1357-
1358-
1359-
1360-
1361QMenu *QMenu::addMenu(const QString &title)-
1362{-
1363 QMenu *menu = new QMenu(title, this);-
1364 addAction(menu->menuAction());-
1365 return menu;-
1366}-
1367-
1368-
1369-
1370-
1371-
1372-
1373-
1374QMenu *QMenu::addMenu(const QIcon &icon, const QString &title)-
1375{-
1376 QMenu *menu = new QMenu(title, this);-
1377 menu->setIcon(icon);-
1378 addAction(menu->menuAction());-
1379 return menu;-
1380}-
1381QAction *QMenu::addSeparator()-
1382{-
1383 QAction *action = new QAction(this);-
1384 action->setSeparator(true);-
1385 addAction(action);-
1386 return action;-
1387}-
1388QAction *QMenu::addSection(const QString &text)-
1389{-
1390 QAction *action = new QAction(text, this);-
1391 action->setSeparator(true);-
1392 addAction(action);-
1393 return action;-
1394}-
1395QAction *QMenu::addSection(const QIcon &icon, const QString &text)-
1396{-
1397 QAction *action = new QAction(icon, text, this);-
1398 action->setSeparator(true);-
1399 addAction(action);-
1400 return action;-
1401}-
1402-
1403-
1404-
1405-
1406-
1407-
1408-
1409QAction *QMenu::insertMenu(QAction *before, QMenu *menu)-
1410{-
1411 QAction *action = menu->menuAction();-
1412 insertAction(before, action);-
1413 return action;-
1414}-
1415QAction *QMenu::insertSeparator(QAction *before)-
1416{-
1417 QAction *action = new QAction(this);-
1418 action->setSeparator(true);-
1419 insertAction(before, action);-
1420 return action;-
1421}-
1422QAction *QMenu::insertSection(QAction *before, const QString &text)-
1423{-
1424 QAction *action = new QAction(text, this);-
1425 action->setSeparator(true);-
1426 insertAction(before, action);-
1427 return action;-
1428}-
1429QAction *QMenu::insertSection(QAction *before, const QIcon &icon, const QString &text)-
1430{-
1431 QAction *action = new QAction(icon, text, this);-
1432 action->setSeparator(true);-
1433 insertAction(before, action);-
1434 return action;-
1435}-
1436void QMenu::setDefaultAction(QAction *act)-
1437{-
1438 d_func()->defaultAction = act;-
1439}-
1440-
1441-
1442-
1443-
1444-
1445-
1446QAction *QMenu::defaultAction() const-
1447{-
1448 return d_func()->defaultAction;-
1449}-
1450void QMenu::setTearOffEnabled(bool b)-
1451{-
1452 QMenuPrivate * const d = d_func();-
1453 if (d->tearoff == b)-
1454 return;-
1455 if (!b)-
1456 hideTearOffMenu();-
1457 d->tearoff = b;-
1458-
1459 d->itemsDirty = true;-
1460 if (isVisible())-
1461 resize(sizeHint());-
1462}-
1463-
1464bool QMenu::isTearOffEnabled() const-
1465{-
1466 return d_func()->tearoff;-
1467}-
1468bool QMenu::isTearOffMenuVisible() const-
1469{-
1470 if (d_func()->tornPopup)-
1471 return d_func()->tornPopup->isVisible();-
1472 return false;-
1473}-
1474void QMenu::hideTearOffMenu()showTearOffMenu(const QPoint &pos)-
1475{-
1476 QMenuPrivate * const d = d_func();-
1477 if (!d->tornPopup
!d->tornPopupDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1478 d->tornPopup = new QTornOffMenu
never executed: d->tornPopup = new QTornOffMenu(this);
never executed: d->tornPopup = new QTornOffMenu(this);
(QWidgetthis);
never executed: d->tornPopup = new QTornOffMenu(this);
0
1479 const QSize &s = sizeHint();-
1480 d->tornPopup->setGeometry(pos.x(), pos.y(), s.width(), s.height());-
1481 d->tornPopup->show();-
1482}
never executed: end of block
0
1483void QMenu::showTearOffMenu()-
1484{-
1485 showTearOffMenu(QCursor::pos());-
1486}
never executed: end of block
0
1487-
1488-
1489-
1490-
1491-
1492-
1493-
1494void QMenu::hideTearOffMenu()-
1495{-
1496 QMenuPrivate * wconst d = d_func()->();-
1497 if (d->
d->tornPopupDescription
TRUEnever evaluated
FALSEnever evaluated
d->tornPopupDescription
TRUEnever evaluated
FALSEnever evaluated
tornPopup
d->tornPopupDescription
TRUEnever evaluated
FALSEnever evaluated
) w{
0
1498 d->tornPopup->close();-
1499-
1500-
1501-
1502-
1503 d->tornPopup = nullptr;-
1504 }
never executed: end of block
0
1505}
never executed: end of block
0
1506-
1507-
1508-
1509-
1510-
1511void QMenu::setActiveAction(QAction *act)-
1512{-
1513 QMenuPrivate * const d = d_func();-
1514 d->setCurrentAction(act, 0);-
1515 if (d->scroll)-
1516 d->scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollCenter);-
1517}-
1518-
1519-
1520-
1521-
1522-
1523-
1524QAction *QMenu::activeAction() const-
1525{-
1526 return d_func()->currentAction;-
1527}-
1528bool QMenu::isEmpty() const-
1529{-
1530 bool ret = true;-
1531 for(int i = 0; ret && i < actions().count(); ++i) {-
1532 const QAction *action = actions().at(i);-
1533 if (!action->isSeparator() && action->isVisible()) {-
1534 ret = false;-
1535 }-
1536 }-
1537 return ret;-
1538}-
1539-
1540-
1541-
1542-
1543-
1544-
1545-
1546void QMenu::clear()-
1547{-
1548 QList<QAction*> acts = actions();-
1549-
1550 for(int i = 0; i < acts.size(); i++) {-
1551 removeAction(acts[i]);-
1552 if (acts[i]->parent() == this && acts[i]->d_func()->widgets.isEmpty())-
1553 delete acts[i];-
1554 }-
1555}-
1556int QMenu::columnCount() const-
1557{-
1558 return d_func()->ncols;-
1559}-
1560-
1561-
1562-
1563-
1564QAction *QMenu::actionAt(const QPoint &pt) const-
1565{-
1566 if (QAction *ret = d_func()->actionAt(pt))-
1567 return ret;-
1568 return 0;-
1569}-
1570-
1571-
1572-
1573-
1574QRect QMenu::actionGeometry(QAction *act) const-
1575{-
1576 return d_func()->actionRect(act);-
1577}-
1578-
1579-
1580-
1581-
1582QSize QMenu::sizeHint() const-
1583{-
1584 const QMenuPrivate * const d = d_func();-
1585 d->updateActionRects();-
1586-
1587 QSize s;-
1588 for (int i = 0; i < d->actionRects.count(); ++i) {-
1589 const QRect &rect = d->actionRects.at(i);-
1590 if (rect.isNull())-
1591 continue;-
1592 if (rect.bottom() >= s.height())-
1593 s.setHeight(rect.y() + rect.height());-
1594 if (rect.right() >= s.width())-
1595 s.setWidth(rect.x() + rect.width());-
1596 }-
1597-
1598-
1599-
1600 QStyleOption opt(0);-
1601 opt.init(this);-
1602 const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this);-
1603 s.rwidth() += style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this) + fw + d->rightmargin;-
1604 s.rheight() += style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, this) + fw + d->bottommargin;-
1605-
1606 return style()->sizeFromContents(QStyle::CT_Menu, &opt,-
1607 s.expandedTo(QApplication::globalStrut()), this);-
1608}-
1609void QMenu::popup(const QPoint &p, QAction *atAction)-
1610{-
1611 QMenuPrivate * const d = d_func();-
1612 if (d->scroll) {-
1613 if (d->scroll->scrollOffset)-
1614 d->itemsDirty = 1;-
1615 d->scroll->scrollOffset = 0;-
1616 d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;-
1617 }-
1618 d->tearoffHighlighted = 0;-
1619 d->motions = 0;-
1620 d->doChildEffects = true;-
1621 d->updateLayoutDirection();-
1622-
1623-
1624-
1625-
1626 setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(d->topCausedWidget()) != 0);-
1627-
1628-
1629 ensurePolished();-
1630 aboutToShow();-
1631 const bool actionListChanged = d->itemsDirty;-
1632 d->updateActionRects();-
1633 QPoint pos;-
1634 QPushButton *causedButton = qobject_cast<QPushButton*>(d->causedPopup.widget);-
1635 if (actionListChanged && causedButton)-
1636 pos = QPushButtonPrivate::get(causedButton)->adjustedMenuPosition();-
1637 else-
1638 pos = p;-
1639-
1640 QSize size = sizeHint();-
1641 QRect screen;-
1642-
1643 bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this);-
1644 if (isEmbedded)-
1645 screen = d->popupGeometry(this);-
1646 else-
1647-
1648 screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));-
1649 const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this);-
1650 bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen);-
1651-
1652-
1653 if (size.height() > screen.height() || size.width() > screen.width()) {-
1654 size = d->adjustMenuSizeForScreen(screen);-
1655 adjustToDesktop = true;-
1656 }-
1657-
1658 if (d->ncols >1 && size.height() < screen.height()) {-
1659 size = d->adjustMenuSizeForScreen(screen);-
1660 adjustToDesktop = true;-
1661 }-
1662 if (d->ncols > 1) {-
1663 pos.setY(screen.top() + desktopFrame);-
1664 } else if (atAction) {-
1665 for (int i = 0, above_height = 0; i < d->actions.count(); i++) {-
1666 QAction *action = d->actions.at(i);-
1667 if (action == atAction) {-
1668 int newY = pos.y() - above_height;-
1669 if (d->scroll && newY < desktopFrame) {-
1670 d->scroll->scrollFlags = d->scroll->scrollFlags-
1671 | QMenuPrivate::QMenuScroller::ScrollUp;-
1672 d->scroll->scrollOffset = newY;-
1673 newY = desktopFrame;-
1674 }-
1675 pos.setY(newY);-
1676-
1677 if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone-
1678 && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) {-
1679 int below_height = above_height + d->scroll->scrollOffset;-
1680 for (int i2 = i; i2 < d->actionRects.count(); i2++)-
1681 below_height += d->actionRects.at(i2).height();-
1682 size.setHeight(below_height);-
1683 }-
1684 break;-
1685 } else {-
1686 above_height += d->actionRects.at(i).height();-
1687 }-
1688 }-
1689 }-
1690-
1691 QPoint mouse = QCursor::pos();-
1692 d->mousePopupPos = mouse;-
1693 const bool snapToMouse = !d->causedPopup.widget && (QRect(p.x() - 3, p.y() - 3, 6, 6).contains(mouse));-
1694-
1695 const QSize menuSize(sizeHint());-
1696 if (adjustToDesktop) {-
1697-
1698 if (isRightToLeft()) {-
1699 if (snapToMouse)-
1700 pos.setX(mouse.x() - size.width());-
1701-
1702-
1703-
1704 if (qobject_cast<QMenuBar*>(d->causedPopup.widget) || qobject_cast<QMenu*>(d->causedPopup.widget))-
1705 pos.rx() -= size.width();-
1706-
1707-
1708 if (pos.x() < screen.left() + desktopFrame)-
1709 pos.setX(qMax(p.x(), screen.left() + desktopFrame));-
1710 if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)-
1711 pos.setX(qMax(p.x() - size.width(), screen.right() - desktopFrame - size.width() + 1));-
1712 } else {-
1713 if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)-
1714 pos.setX(screen.right() - desktopFrame - size.width() + 1);-
1715 if (pos.x() < screen.left() + desktopFrame)-
1716 pos.setX(screen.left() + desktopFrame);-
1717 }-
1718 if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) {-
1719 if(snapToMouse)-
1720 pos.setY(qMin(mouse.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1));-
1721 else-
1722 pos.setY(qMax(p.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1));-
1723 } else if (pos.y() < screen.top() + desktopFrame) {-
1724 pos.setY(screen.top() + desktopFrame);-
1725 }-
1726-
1727 if (pos.y() < screen.top() + desktopFrame)-
1728 pos.setY(screen.top() + desktopFrame);-
1729 if (pos.y() + menuSize.height() - 1 > screen.bottom() - desktopFrame) {-
1730 if (d->scroll) {-
1731 d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown);-
1732 int y = qMax(screen.y(),pos.y());-
1733 size.setHeight(screen.bottom() - (desktopFrame * 2) - y);-
1734 } else {-
1735-
1736 pos.setY(screen.bottom() - size.height() + 1);-
1737 }-
1738 }-
1739 }-
1740 const int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this);-
1741 QMenu *caused = qobject_cast<QMenu*>(d_func()->causedPopup.widget);-
1742 if (caused && caused->geometry().width() + menuSize.width() + subMenuOffset < screen.width()) {-
1743 QRect parentActionRect(caused->d_func()->actionRect(caused->d_func()->currentAction));-
1744 const QPoint actionTopLeft = caused->mapToGlobal(parentActionRect.topLeft());-
1745 parentActionRect.moveTopLeft(actionTopLeft);-
1746 if (isRightToLeft()) {-
1747 if ((pos.x() + menuSize.width() > parentActionRect.left() - subMenuOffset)-
1748 && (pos.x() < parentActionRect.right()))-
1749 {-
1750 pos.rx() = parentActionRect.left() - menuSize.width();-
1751 if (pos.x() < screen.x())-
1752 pos.rx() = parentActionRect.right();-
1753 if (pos.x() + menuSize.width() > screen.x() + screen.width())-
1754 pos.rx() = screen.x();-
1755 }-
1756 } else {-
1757 if ((pos.x() < parentActionRect.right() + subMenuOffset)-
1758 && (pos.x() + menuSize.width() > parentActionRect.left()))-
1759 {-
1760 pos.rx() = parentActionRect.right();-
1761 if (pos.x() + menuSize.width() > screen.x() + screen.width())-
1762 pos.rx() = parentActionRect.left() - menuSize.width();-
1763 if (pos.x() < screen.x())-
1764 pos.rx() = screen.x() + screen.width() - menuSize.width();-
1765 }-
1766 }-
1767 }-
1768 setGeometry(QRect(pos, size));-
1769-
1770 int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll;-
1771 int vGuess = QEffects::DownScroll;-
1772 if (isRightToLeft()) {-
1773 if ((snapToMouse && (pos.x() + size.width() / 2 > mouse.x())) ||-
1774 (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 > d->causedPopup.widget->x()))-
1775 hGuess = QEffects::RightScroll;-
1776 } else {-
1777 if ((snapToMouse && (pos.x() + size.width() / 2 < mouse.x())) ||-
1778 (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 < d->causedPopup.widget->x()))-
1779 hGuess = QEffects::LeftScroll;-
1780 }-
1781-
1782-
1783 if ((snapToMouse && (pos.y() + size.height() / 2 < mouse.y())) ||-
1784 (qobject_cast<QMenuBar*>(d->causedPopup.widget) &&-
1785 pos.y() + size.width() / 2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y()))-
1786 vGuess = QEffects::UpScroll;-
1787-
1788 if (QApplication::isEffectEnabled(Qt::UI_AnimateMenu)) {-
1789 bool doChildEffects = true;-
1790-
1791 if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget)) {-
1792 doChildEffects = mb->d_func()->doChildEffects;-
1793 mb->d_func()->doChildEffects = false;-
1794 } else-
1795-
1796 if (QMenu *m = qobject_cast<QMenu*>(d->causedPopup.widget)) {-
1797 doChildEffects = m->d_func()->doChildEffects;-
1798 m->d_func()->doChildEffects = false;-
1799 }-
1800-
1801 if (doChildEffects) {-
1802 if (QApplication::isEffectEnabled(Qt::UI_FadeMenu))-
1803 qFadeEffect(this);-
1804 else if (d->causedPopup.widget)-
1805 qScrollEffect(this, qobject_cast<QMenu*>(d->causedPopup.widget) ? hGuess : vGuess);-
1806 else-
1807 qScrollEffect(this, hGuess | vGuess);-
1808 } else {-
1809-
1810 qFadeEffect(0);-
1811 qScrollEffect(0);-
1812-
1813 show();-
1814 }-
1815 } else-
1816-
1817 {-
1818 show();-
1819 }-
1820-
1821-
1822 QAccessibleEvent event(this, QAccessible::PopupMenuStart);-
1823 QAccessible::updateAccessibility(&event);-
1824-
1825}-
1826QAction *QMenu::exec()-
1827{-
1828 return exec(pos());-
1829}-
1830QAction *QMenu::exec(const QPoint &p, QAction *action)-
1831{-
1832 QMenuPrivate * const d = d_func();-
1833 ensurePolished();-
1834 createWinId();-
1835 QEventLoop eventLoop;-
1836 d->eventLoop = &eventLoop;-
1837 popup(p, action);-
1838-
1839 QPointer<QObject> guard = this;-
1840 (void) eventLoop.exec();-
1841 if (guard.isNull())-
1842 return 0;-
1843-
1844 action = d->syncAction;-
1845 d->syncAction = 0;-
1846 d->eventLoop = 0;-
1847 return action;-
1848}-
1849QAction *QMenu::exec(QList<QAction*> actions, const QPoint &pos, QAction *at, QWidget *parent)-
1850-
1851{-
1852 QMenu menu(parent);-
1853 menu.addActions(actions);-
1854 return menu.exec(pos, at);-
1855}-
1856-
1857-
1858-
1859-
1860void QMenu::hideEvent(QHideEvent *)-
1861{-
1862 QMenuPrivate * const d = d_func();-
1863 aboutToHide();-
1864 if (d->eventLoop)-
1865 d->eventLoop->exit();-
1866 d->setCurrentAction(0);-
1867-
1868 QAccessibleEvent event(this, QAccessible::PopupMenuEnd);-
1869 QAccessible::updateAccessibility(&event);-
1870-
1871-
1872 if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget))-
1873 mb->d_func()->setCurrentAction(0);-
1874-
1875 d->mouseDown = 0;-
1876 d->hasHadMouse = false;-
1877 if (d->activeMenu)-
1878 d->hideMenu(d->activeMenu);-
1879 d->causedPopup.widget = 0;-
1880 d->causedPopup.action = 0;-
1881 if (d->scroll)-
1882 d->scroll->scrollTimer.stop();-
1883}-
1884-
1885-
1886-
1887-
1888void QMenu::paintEvent(QPaintEvent *e)-
1889{-
1890 QMenuPrivate * const d = d_func();-
1891 d->updateActionRects();-
1892 QPainter p(this);-
1893 QRegion emptyArea = QRegion(rect());-
1894-
1895 QStyleOptionMenuItem menuOpt;-
1896 menuOpt.initFrom(this);-
1897 menuOpt.state = QStyle::State_None;-
1898 menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;-
1899 menuOpt.maxIconWidth = 0;-
1900 menuOpt.tabWidth = 0;-
1901 style()->drawPrimitive(QStyle::PE_PanelMenu, &menuOpt, &p, this);-
1902-
1903-
1904 for (int i = 0; i < d->actions.count(); ++i) {-
1905 QAction *action = d->actions.at(i);-
1906 QRect adjustedActionRect = d->actionRects.at(i);-
1907 if (!e->rect().intersects(adjustedActionRect)-
1908 || d->widgetItems.value(action))-
1909 continue;-
1910-
1911 QRegion adjustedActionReg(adjustedActionRect);-
1912 emptyArea -= adjustedActionReg;-
1913 p.setClipRegion(adjustedActionReg);-
1914-
1915 QStyleOptionMenuItem opt;-
1916 initStyleOption(&opt, action);-
1917 opt.rect = adjustedActionRect;-
1918 style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this);-
1919 }-
1920-
1921 const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);-
1922-
1923 if (d->scroll) {-
1924 menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;-
1925 menuOpt.state |= QStyle::State_Enabled;-
1926 if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) {-
1927 menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight());-
1928 emptyArea -= QRegion(menuOpt.rect);-
1929 p.setClipRect(menuOpt.rect);-
1930 style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);-
1931 }-
1932 if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) {-
1933 menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2),-
1934 d->scrollerHeight());-
1935 emptyArea -= QRegion(menuOpt.rect);-
1936 menuOpt.state |= QStyle::State_DownArrow;-
1937 p.setClipRect(menuOpt.rect);-
1938 style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);-
1939 }-
1940 }-
1941-
1942 if (d->tearoff) {-
1943 menuOpt.menuItemType = QStyleOptionMenuItem::TearOff;-
1944 menuOpt.rect.setRect(fw, fw, width() - (fw * 2),-
1945 style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this));-
1946 if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)-
1947 menuOpt.rect.translate(0, d->scrollerHeight());-
1948 emptyArea -= QRegion(menuOpt.rect);-
1949 p.setClipRect(menuOpt.rect);-
1950 menuOpt.state = QStyle::State_None;-
1951 if (d->tearoffHighlighted)-
1952 menuOpt.state |= QStyle::State_Selected;-
1953 style()->drawControl(QStyle::CE_MenuTearoff, &menuOpt, &p, this);-
1954 }-
1955-
1956 if (fw) {-
1957 QRegion borderReg;-
1958 borderReg += QRect(0, 0, fw, height());-
1959 borderReg += QRect(width()-fw, 0, fw, height());-
1960 borderReg += QRect(0, 0, width(), fw);-
1961 borderReg += QRect(0, height()-fw, width(), fw);-
1962 p.setClipRegion(borderReg);-
1963 emptyArea -= borderReg;-
1964 QStyleOptionFrame frame;-
1965 frame.rect = rect();-
1966 frame.palette = palette();-
1967 frame.state = QStyle::State_None;-
1968 frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuPanelWidth);-
1969 frame.midLineWidth = 0;-
1970 style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, &p, this);-
1971 }-
1972-
1973-
1974 p.setClipRegion(emptyArea);-
1975 menuOpt.state = QStyle::State_None;-
1976 menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea;-
1977 menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;-
1978 menuOpt.rect = rect();-
1979 menuOpt.menuRect = rect();-
1980 style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);-
1981}-
1982-
1983-
1984-
1985-
1986-
1987void QMenu::wheelEvent(QWheelEvent *e)-
1988{-
1989 QMenuPrivate * const d = d_func();-
1990 if (d->scroll && rect().contains(e->pos()))-
1991 d->scrollMenu(e->delta() > 0 ?-
1992 QMenuPrivate::QMenuScroller::ScrollUp : QMenuPrivate::QMenuScroller::ScrollDown);-
1993}-
1994-
1995-
1996-
1997-
1998-
1999void QMenu::mousePressEvent(QMouseEvent *e)-
2000{-
2001 QMenuPrivate * const d = d_func();-
2002 if (d->aboutToHide || d->mouseEventTaken(e))-
2003 return;-
2004-
2005-
2006-
2007-
2008 if ((e->pos().isNull() && !e->screenPos().isNull()) || !rect().contains(e->pos())) {-
2009 if (d->noReplayFor-
2010 && QRect(d->noReplayFor->mapToGlobal(QPoint()), d->noReplayFor->size()).contains(e->globalPos()))-
2011 setAttribute(Qt::WA_NoMouseReplay);-
2012 if (d->eventLoop)-
2013 d->syncAction = 0;-
2014 d->hideUpToMenuBar();-
2015 return;-
2016 }-
2017 d->mouseDown = this;-
2018-
2019 QAction *action = d->actionAt(e->pos());-
2020 d->setCurrentAction(action, 20);-
2021 update();-
2022}-
2023-
2024-
2025-
2026-
2027void QMenu::mouseReleaseEvent(QMouseEvent *e)-
2028{-
2029 QMenuPrivate * const d = d_func();-
2030 if (d->aboutToHide || d->mouseEventTaken(e))-
2031 return;-
2032 if(d->mouseDown != this) {-
2033 d->mouseDown = 0;-
2034 return;-
2035 }-
2036-
2037 d->mouseDown = 0;-
2038 d->setSyncAction();-
2039 QAction *action = d->actionAt(e->pos());-
2040-
2041 if (action && action == d->currentAction) {-
2042 if (!action->menu()){-
2043-
2044-
2045-
2046-
2047 d->activateAction(action, QAction::Trigger);-
2048 }-
2049 } else if ((!action || action->isEnabled()) && d->hasMouseMoved(e->globalPos())) {-
2050 d->hideUpToMenuBar();-
2051 }-
2052}-
2053-
2054-
2055-
2056-
2057void QMenu::changeEvent(QEvent *e)-
2058{-
2059 QMenuPrivate * const d = d_func();-
2060 if (e->type() == QEvent::StyleChange || e->type() == QEvent::FontChange ||-
2061 e->type() == QEvent::LayoutDirectionChange) {-
2062 d->itemsDirty = 1;-
2063 setMouseTracking(style()->styleHint(QStyle::SH_Menu_MouseTracking, 0, this));-
2064 if (isVisible())-
2065 resize(sizeHint());-
2066 if (!style()->styleHint(QStyle::SH_Menu_Scrollable, 0, this)) {-
2067 delete d->scroll;-
2068 d->scroll = 0;-
2069 } else if (!d->scroll) {-
2070 d->scroll = new QMenuPrivate::QMenuScroller;-
2071 d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;-
2072 }-
2073 } else if (e->type() == QEvent::EnabledChange) {-
2074 if (d->tornPopup)-
2075 d->tornPopup->setEnabled(isEnabled());-
2076 d->menuAction->setEnabled(isEnabled());-
2077 if (!d->platformMenu.isNull())-
2078 d->platformMenu->setEnabled(isEnabled());-
2079 }-
2080 QWidget::changeEvent(e);-
2081}-
2082-
2083-
2084-
2085-
2086-
2087bool-
2088QMenu::event(QEvent *e)-
2089{-
2090 QMenuPrivate * const d = d_func();-
2091 switch (e->type()) {-
2092 case QEvent::Polish:-
2093 d->updateLayoutDirection();-
2094 break;-
2095 case QEvent::ShortcutOverride: {-
2096 QKeyEvent *kev = static_cast<QKeyEvent*>(e);-
2097 if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down-
2098 || kev->key() == Qt::Key_Left || kev->key() == Qt::Key_Right-
2099 || kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return-
2100 || kev->matches(QKeySequence::Cancel)) {-
2101 e->accept();-
2102 return true;-
2103 }-
2104 }-
2105 break;-
2106 case QEvent::KeyPress: {-
2107 QKeyEvent *ke = (QKeyEvent*)e;-
2108 if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {-
2109 keyPressEvent(ke);-
2110 return true;-
2111 }-
2112 } break;-
2113 case QEvent::MouseButtonPress:-
2114 case QEvent::ContextMenu: {-
2115 bool canPopup = true;-
2116 if (e->type() == QEvent::MouseButtonPress)-
2117 canPopup = (static_cast<QMouseEvent*>(e)->button() == Qt::LeftButton);-
2118 if (canPopup && d->delayState.timer.isActive()) {-
2119 d->delayState.stop();-
2120 internalDelayedPopup();-
2121 }-
2122 }-
2123 break;-
2124 case QEvent::Resize: {-
2125 QStyleHintReturnMask menuMask;-
2126 QStyleOption option;-
2127 option.initFrom(this);-
2128 if (style()->styleHint(QStyle::SH_Menu_Mask, &option, this, &menuMask)) {-
2129 setMask(menuMask.region);-
2130 }-
2131 d->itemsDirty = 1;-
2132 d->updateActionRects();-
2133 break; }-
2134 case QEvent::Show:-
2135 d->mouseDown = 0;-
2136 d->updateActionRects();-
2137 d->sloppyState.reset();-
2138 if (d->currentAction)-
2139 d->popupAction(d->currentAction, 0, false);-
2140 break;-
2141-
2142 case QEvent::ToolTip:-
2143 if (d->toolTipsVisible) {-
2144 const QHelpEvent *ev = static_cast<const QHelpEvent*>(e);-
2145 if (const QAction *action = actionAt(ev->pos())) {-
2146 const QString toolTip = action->d_func()->tooltip;-
2147 if (!toolTip.isEmpty())-
2148 QToolTip::showText(ev->globalPos(), toolTip, this);-
2149 return true;-
2150 }-
2151 }-
2152 break;-
2153-
2154-
2155 case QEvent::QueryWhatsThis:-
2156 e->setAccepted(d->whatsThis.size());-
2157 if (QAction *action = d->actionAt(static_cast<QHelpEvent*>(e)->pos())) {-
2158 if (action->whatsThis().size() || action->menu())-
2159 e->accept();-
2160 }-
2161 return true;-
2162-
2163 default:-
2164 break;-
2165 }-
2166 return QWidget::event(e);-
2167}-
2168-
2169-
2170-
2171-
2172bool QMenu::focusNextPrevChild(bool next)-
2173{-
2174 setFocus();-
2175 QKeyEvent ev(QEvent::KeyPress, next ? Qt::Key_Tab : Qt::Key_Backtab, Qt::NoModifier);-
2176 keyPressEvent(&ev);-
2177 return true;-
2178}-
2179-
2180-
2181-
2182-
2183void QMenu::keyPressEvent(QKeyEvent *e)-
2184{-
2185 QMenuPrivate * const d = d_func();-
2186 d->updateActionRects();-
2187 int key = e->key();-
2188 if (isRightToLeft()) {-
2189 if (key == Qt::Key_Left)-
2190 key = Qt::Key_Right;-
2191 else if (key == Qt::Key_Right)-
2192 key = Qt::Key_Left;-
2193 }-
2194-
2195 if (key == Qt::Key_Tab)-
2196 key = Qt::Key_Down;-
2197 if (key == Qt::Key_Backtab)-
2198 key = Qt::Key_Up;-
2199-
2200-
2201 bool key_consumed = false;-
2202 switch(key) {-
2203 case Qt::Key_Home:-
2204 key_consumed = true;-
2205 if (d->scroll)-
2206 d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollTop, true);-
2207 break;-
2208 case Qt::Key_End:-
2209 key_consumed = true;-
2210 if (d->scroll)-
2211 d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollBottom, true);-
2212 break;-
2213 case Qt::Key_PageUp:-
2214 key_consumed = true;-
2215 if (d->currentAction && d->scroll) {-
2216 if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)-
2217 d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollUp, true, true);-
2218 else-
2219 d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollTop, true);-
2220 }-
2221 break;-
2222 case Qt::Key_PageDown:-
2223 key_consumed = true;-
2224 if (d->currentAction && d->scroll) {-
2225 if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)-
2226 d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollDown, true, true);-
2227 else-
2228 d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollBottom, true);-
2229 }-
2230 break;-
2231 case Qt::Key_Up:-
2232 case Qt::Key_Down: {-
2233 key_consumed = true;-
2234 QAction *nextAction = 0;-
2235 QMenuPrivate::QMenuScroller::ScrollLocation scroll_loc = QMenuPrivate::QMenuScroller::ScrollStay;-
2236 if (!d->currentAction) {-
2237 if(key == Qt::Key_Down) {-
2238 for(int i = 0; i < d->actions.count(); ++i) {-
2239 QAction *act = d->actions.at(i);-
2240 if (d->actionRects.at(i).isNull())-
2241 continue;-
2242 if (!act->isSeparator() &&-
2243 (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)-
2244 || act->isEnabled())) {-
2245 nextAction = act;-
2246 break;-
2247 }-
2248 }-
2249 } else {-
2250 for(int i = d->actions.count()-1; i >= 0; --i) {-
2251 QAction *act = d->actions.at(i);-
2252 if (d->actionRects.at(i).isNull())-
2253 continue;-
2254 if (!act->isSeparator() &&-
2255 (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)-
2256 || act->isEnabled())) {-
2257 nextAction = act;-
2258 break;-
2259 }-
2260 }-
2261 }-
2262 } else {-
2263 for(int i = 0, y = 0; !nextAction && i < d->actions.count(); i++) {-
2264 QAction *act = d->actions.at(i);-
2265 if (act == d->currentAction) {-
2266 if (key == Qt::Key_Up) {-
2267 for(int next_i = i-1; true; next_i--) {-
2268 if (next_i == -1) {-
2269 if(!style()->styleHint(QStyle::SH_Menu_SelectionWrap, 0, this))-
2270 break;-
2271 if (d->scroll)-
2272 scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;-
2273 next_i = d->actionRects.count()-1;-
2274 }-
2275 QAction *next = d->actions.at(next_i);-
2276 if (next == d->currentAction)-
2277 break;-
2278 if (d->actionRects.at(next_i).isNull())-
2279 continue;-
2280 if (next->isSeparator() ||-
2281 (!next->isEnabled() &&-
2282 !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)))-
2283 continue;-
2284 nextAction = next;-
2285 if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) {-
2286 int topVisible = d->scrollerHeight();-
2287 if (d->tearoff)-
2288 topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);-
2289 if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height())-
2290 scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop;-
2291 }-
2292 break;-
2293 }-
2294 if (!nextAction && d->tearoff)-
2295 d->tearoffHighlighted = 1;-
2296 } else {-
2297 y += d->actionRects.at(i).height();-
2298 for(int next_i = i+1; true; next_i++) {-
2299 if (next_i == d->actionRects.count()) {-
2300 if(!style()->styleHint(QStyle::SH_Menu_SelectionWrap, 0, this))-
2301 break;-
2302 if (d->scroll)-
2303 scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop;-
2304 next_i = 0;-
2305 }-
2306 QAction *next = d->actions.at(next_i);-
2307 if (next == d->currentAction)-
2308 break;-
2309 if (d->actionRects.at(next_i).isNull())-
2310 continue;-
2311 if (next->isSeparator() ||-
2312 (!next->isEnabled() &&-
2313 !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)))-
2314 continue;-
2315 nextAction = next;-
2316 if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) {-
2317 int bottomVisible = height() - d->scrollerHeight();-
2318 if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)-
2319 bottomVisible -= d->scrollerHeight();-
2320 if (d->tearoff)-
2321 bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);-
2322 if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible)-
2323 scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;-
2324 }-
2325 break;-
2326 }-
2327 }-
2328 break;-
2329 }-
2330 y += d->actionRects.at(i).height();-
2331 }-
2332 }-
2333 if (nextAction) {-
2334 if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) {-
2335 d->scroll->scrollTimer.stop();-
2336 d->scrollMenu(nextAction, scroll_loc);-
2337 }-
2338 d->setCurrentAction(nextAction, -1, QMenuPrivate::SelectedFromKeyboard);-
2339 }-
2340 break; }-
2341-
2342 case Qt::Key_Right:-
2343 if (d->currentAction && d->currentAction->isEnabled() && d->currentAction->menu()) {-
2344 d->popupAction(d->currentAction, 0, true);-
2345 key_consumed = true;-
2346 break;-
2347 }-
2348-
2349 case Qt::Key_Left: {-
2350 if (d->currentAction && !d->scroll) {-
2351 QAction *nextAction = 0;-
2352 if (key == Qt::Key_Left) {-
2353 QRect actionR = d->actionRect(d->currentAction);-
2354 for(int x = actionR.left()-1; !nextAction && x >= 0; x--)-
2355 nextAction = d->actionAt(QPoint(x, actionR.center().y()));-
2356 } else {-
2357 QRect actionR = d->actionRect(d->currentAction);-
2358 for(int x = actionR.right()+1; !nextAction && x < width(); x++)-
2359 nextAction = d->actionAt(QPoint(x, actionR.center().y()));-
2360 }-
2361 if (nextAction) {-
2362 d->setCurrentAction(nextAction, -1, QMenuPrivate::SelectedFromKeyboard);-
2363 key_consumed = true;-
2364 }-
2365 }-
2366 if (!key_consumed && key == Qt::Key_Left && qobject_cast<QMenu*>(d->causedPopup.widget)) {-
2367 QPointer<QWidget> caused = d->causedPopup.widget;-
2368 d->hideMenu(this);-
2369 if (caused)-
2370 caused->setFocus();-
2371 key_consumed = true;-
2372 }-
2373 break; }-
2374-
2375 case Qt::Key_Alt:-
2376 if (d->tornoff)-
2377 break;-
2378-
2379 key_consumed = true;-
2380 if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this))-
2381 {-
2382 d->hideMenu(this);-
2383-
2384 if (QMenuBar *mb = qobject_cast<QMenuBar*>(QApplication::focusWidget())) {-
2385 mb->d_func()->setKeyboardMode(false);-
2386 }-
2387-
2388 }-
2389 break;-
2390-
2391 case Qt::Key_Space:-
2392 if (!style()->styleHint(QStyle::SH_Menu_SpaceActivatesItem, 0, this))-
2393 break;-
2394-
2395-
2396-
2397-
2398 case Qt::Key_Return:-
2399 case Qt::Key_Enter: {-
2400 if (!d->currentAction) {-
2401 d->setFirstActionActive();-
2402 key_consumed = true;-
2403 break;-
2404 }-
2405-
2406 d->setSyncAction();-
2407-
2408 if (d->currentAction->menu())-
2409 d->popupAction(d->currentAction, 0, true);-
2410 else-
2411 d->activateAction(d->currentAction, QAction::Trigger);-
2412 key_consumed = true;-
2413 break; }-
2414-
2415-
2416 case Qt::Key_F1:-
2417 if (!d->currentAction || d->currentAction->whatsThis().isNull())-
2418 break;-
2419 QWhatsThis::enterWhatsThisMode();-
2420 d->activateAction(d->currentAction, QAction::Trigger);-
2421 return;-
2422-
2423 default:-
2424 key_consumed = false;-
2425 }-
2426-
2427 if (!key_consumed && (e->matches(QKeySequence::Cancel)-
2428-
2429-
2430-
2431 )) {-
2432 key_consumed = true;-
2433 if (d->tornoff) {-
2434 close();-
2435 return;-
2436 }-
2437 {-
2438 QPointer<QWidget> caused = d->causedPopup.widget;-
2439 d->hideMenu(this);-
2440-
2441 if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {-
2442 mb->d_func()->setCurrentAction(d->menuAction);-
2443 mb->d_func()->setKeyboardMode(true);-
2444 }-
2445-
2446 }-
2447 }-
2448-
2449 if (!key_consumed) {-
2450 if ((!e->modifiers() || e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ShiftModifier) &&-
2451 e->text().length()==1) {-
2452 bool activateAction = false;-
2453 QAction *nextAction = 0;-
2454 if (style()->styleHint(QStyle::SH_Menu_KeyboardSearch, 0, this) && !e->modifiers()) {-
2455 int best_match_count = 0;-
2456 d->searchBufferTimer.start(2000, this);-
2457 d->searchBuffer += e->text();-
2458 for(int i = 0; i < d->actions.size(); ++i) {-
2459 int match_count = 0;-
2460 if (d->actionRects.at(i).isNull())-
2461 continue;-
2462 QAction *act = d->actions.at(i);-
2463 const QString act_text = act->text();-
2464 for(int c = 0; c < d->searchBuffer.size(); ++c) {-
2465 if(act_text.indexOf(d->searchBuffer.at(c), 0, Qt::CaseInsensitive) != -1)-
2466 ++match_count;-
2467 }-
2468 if(match_count > best_match_count) {-
2469 best_match_count = match_count;-
2470 nextAction = act;-
2471 }-
2472 }-
2473 }-
2474-
2475 else {-
2476 int clashCount = 0;-
2477 QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;-
2478 QChar c = e->text().at(0).toUpper();-
2479 for(int i = 0; i < d->actions.size(); ++i) {-
2480 if (d->actionRects.at(i).isNull())-
2481 continue;-
2482 QAction *act = d->actions.at(i);-
2483 QKeySequence sequence = QKeySequence::mnemonic(act->text());-
2484 int key = sequence[0] & 0xffff;-
2485 if (key == c.unicode()) {-
2486 clashCount++;-
2487 if (!first)-
2488 first = act;-
2489 if (act == d->currentAction)-
2490 currentSelected = act;-
2491 else if (!firstAfterCurrent && currentSelected)-
2492 firstAfterCurrent = act;-
2493 }-
2494 }-
2495 if (clashCount == 1)-
2496 activateAction = true;-
2497 if (clashCount >= 1) {-
2498 if (clashCount == 1 || !currentSelected || !firstAfterCurrent)-
2499 nextAction = first;-
2500 else-
2501 nextAction = firstAfterCurrent;-
2502 }-
2503 }-
2504-
2505 if (nextAction) {-
2506 key_consumed = true;-
2507 if(d->scroll)-
2508 d->scrollMenu(nextAction, QMenuPrivate::QMenuScroller::ScrollCenter, false);-
2509 d->setCurrentAction(nextAction, 0, QMenuPrivate::SelectedFromElsewhere, true);-
2510 if (!nextAction->menu() && activateAction) {-
2511 d->setSyncAction();-
2512 d->activateAction(nextAction, QAction::Trigger);-
2513 }-
2514 }-
2515 }-
2516 if (!key_consumed) {-
2517-
2518 if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->topCausedWidget())) {-
2519 QAction *oldAct = mb->d_func()->currentAction;-
2520 QApplication::sendEvent(mb, e);-
2521 if (mb->d_func()->currentAction != oldAct)-
2522 key_consumed = true;-
2523 }-
2524-
2525 }-
2526-
2527-
2528-
2529-
2530-
2531 }-
2532 if (key_consumed)-
2533 e->accept();-
2534 else-
2535 e->ignore();-
2536}-
2537-
2538-
2539-
2540-
2541void QMenu::mouseMoveEvent(QMouseEvent *e)-
2542{-
2543 QMenuPrivate * const d = d_func();-
2544 if (!isVisible() || d->aboutToHide || d->mouseEventTaken(e))-
2545 return;-
2546-
2547 d->motions++;-
2548 if (d->motions == 0)-
2549 return;-
2550-
2551 d->hasHadMouse = d->hasHadMouse || rect().contains(e->pos());-
2552-
2553 QAction *action = d->actionAt(e->pos());-
2554 if ((!action || action->isSeparator()) && !d->sloppyState.enabled()) {-
2555 if (d->hasHadMouse-
2556 || (!d->currentAction || !d->currentAction->menu() || !d->currentAction->menu()->isVisible())) {-
2557 d->setCurrentAction(action);-
2558 }-
2559 return;-
2560 }-
2561-
2562 if (e->buttons())-
2563 d->mouseDown = this;-
2564-
2565 if (d->activeMenu)-
2566 d->activeMenu->d_func()->setCurrentAction(0);-
2567-
2568 QMenuSloppyState::MouseEventResult sloppyEventResult = d->sloppyState.processMouseEvent(e->localPos(), action, d->currentAction);-
2569 if (sloppyEventResult == QMenuSloppyState::EventShouldBePropagated) {-
2570 d->setCurrentAction(action, d->mousePopupDelay);-
2571 } else if (sloppyEventResult == QMenuSloppyState::EventDiscardsSloppyState) {-
2572 d->sloppyState.reset();-
2573 d->hideMenu(d->activeMenu);-
2574 }-
2575}-
2576-
2577-
2578-
2579-
2580void QMenu::enterEvent(QEvent *)-
2581{-
2582 QMenuPrivate * const d = d_func();-
2583 d->hasReceievedEnter = true;-
2584 d->sloppyState.enter();-
2585 d->motions = -1;-
2586}-
2587-
2588-
2589-
2590-
2591void QMenu::leaveEvent(QEvent *)-
2592{-
2593 QMenuPrivate * const d = d_func();-
2594 d->hasReceievedEnter = false;-
2595 if (!d->activeMenu && d->currentAction)-
2596 setActiveAction(0);-
2597}-
2598-
2599-
2600-
2601-
2602void-
2603QMenu::timerEvent(QTimerEvent *e)-
2604{-
2605 QMenuPrivate * const d = d_func();-
2606 if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) {-
2607 d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection);-
2608 if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone)-
2609 d->scroll->scrollTimer.stop();-
2610 } else if (d->delayState.timer.timerId() == e->timerId()) {-
2611 if (d->currentAction && !d->currentAction->menu())-
2612 return;-
2613 d->delayState.stop();-
2614 d->sloppyState.stopTimer();-
2615 internalDelayedPopup();-
2616 } else if (d->sloppyState.isTimerId(e->timerId())) {-
2617 d->sloppyState.timeout();-
2618 } else if(d->searchBufferTimer.timerId() == e->timerId()) {-
2619 d->searchBuffer.clear();-
2620 }-
2621}-
2622-
2623static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item, QPlatformMenu *itemsMenu)-
2624{-
2625 item->setText(action->text());-
2626 item->setIsSeparator(action->isSeparator());-
2627 if (action->isIconVisibleInMenu()
action->isIconVisibleInMenu()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
2628 item->setIcon(action->icon());-
2629 if (QWidget *w = action->parentWidget()
QWidget *w = a...parentWidget()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
2630 QStyleOption opt;-
2631 opt.init(w);-
2632 item->setIconSize(w->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, w));-
2633 }
never executed: end of block
else {
0
2634 QStyleOption opt;-
2635 item->setIconSize((static_cast<QApplication *>(QCoreApplication::instance()))->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, 0));-
2636 }
never executed: end of block
0
2637 } else {-
2638 item->setIcon(QIcon());-
2639 }
never executed: end of block
0
2640 item->setVisible(action->isVisible());-
2641 item->setShortcut(action->shortcut());-
2642 item->setCheckable(action->isCheckable());-
2643 item->setChecked(action->isChecked());-
2644 item->setHasExclusiveGroup(action->actionGroup() && action->actionGroup()->isExclusive());-
2645 item->setFont(action->font());-
2646 item->setRole((QPlatformMenuItem::MenuRole) action->menuRole());-
2647 item->setEnabled(action->isEnabled());-
2648-
2649 if (action->menu()
action->menu()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
2650 if (!action->menu()->platformMenu()
!action->menu(...platformMenu()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2651 action->menu()->setPlatformMenu(itemsMenu->createSubMenu());
never executed: action->menu()->setPlatformMenu(itemsMenu->createSubMenu());
0
2652 item->setMenu(action->menu()->platformMenu());-
2653 }
never executed: end of block
else {
0
2654 item->setMenu(0);-
2655 }
never executed: end of block
0
2656}-
2657-
2658-
2659-
2660-
2661void QMenu::actionEvent(QActionEvent *e)-
2662{-
2663 QMenuPrivate * const d = d_func();-
2664 d->itemsDirty = 1;-
2665 setAttribute(Qt::WA_Resized, false);-
2666 if (d->tornPopup)-
2667 d->tornPopup->syncWithMenu(this, e);-
2668 if (e->type() == QEvent::ActionAdded) {-
2669 if(!d->tornoff) {-
2670 connect(e->action(), qFlagLocation("2""triggered()" "\0" __FILE__ ":" "3260""3303"), this, qFlagLocation("1""_q_actionTriggered()" "\0" __FILE__ ":" "3260""3303"));-
2671 connect(e->action(), qFlagLocation("2""hovered()" "\0" __FILE__ ":" "3261""3304"), this, qFlagLocation("1""_q_actionHovered()" "\0" __FILE__ ":" "3261""3304"));-
2672 }-
2673 if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {-
2674 QWidget *widget = wa->requestWidget(this);-
2675 if (widget)-
2676 d->widgetItems.insert(wa, widget);-
2677 }-
2678 } else if (e->type() == QEvent::ActionRemoved) {-
2679 e->action()->disconnect(this);-
2680 if (e->action() == d->currentAction)-
2681 d->currentAction = 0;-
2682 if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {-
2683 if (QWidget *widget = d->widgetItems.value(wa)) {-
2684 wa->releaseWidget(widget);-
2685 }-
2686 }-
2687 d->widgetItems.remove(e->action());-
2688 }-
2689-
2690 if (!d->platformMenu.isNull()) {-
2691 if (e->type() == QEvent::ActionAdded) {-
2692 QPlatformMenuItem *menuItem = d->platformMenu->createMenuItem();-
2693 menuItem->setTag(reinterpret_cast<quintptr>(e->action()));-
2694 QObject::connect(menuItem, qFlagLocation("2""activated()" "\0" __FILE__ ":" "3294""3337"), e->action(), qFlagLocation("1""trigger()" "\0" __FILE__ ":" "3294""3337"));-
2695 QObject::connect(menuItem, qFlagLocation("2""hovered()" "\0" __FILE__ ":" "3295""3338"), e->action(), qFlagLocation("2""hovered()" "\0" __FILE__ ":" "3295""3338"));-
2696 copyActionToPlatformItem(e->action(), menuItem, d->platformMenu);-
2697 QPlatformMenuItem* beforeItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->before()));-
2698 d->platformMenu->insertMenuItem(menuItem, beforeItem);-
2699 } else if (e->type() == QEvent::ActionRemoved) {-
2700 QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->action()));-
2701 d->platformMenu->removeMenuItem(menuItem);-
2702 delete menuItem;-
2703 } else if (e->type() == QEvent::ActionChanged) {-
2704 QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast<quintptr>(e->action()));-
2705 if (menuItem) {-
2706 copyActionToPlatformItem(e->action(), menuItem, d->platformMenu);-
2707 d->platformMenu->syncMenuItem(menuItem);-
2708 }-
2709 }-
2710-
2711 d->platformMenu->syncSeparatorsCollapsible(d->collapsibleSeparators);-
2712 }-
2713 if (isVisible()) {-
2714 d->updateActionRects();-
2715 resize(sizeHint());-
2716 update();-
2717 }-
2718}-
2719-
2720-
2721-
2722-
2723void QMenu::internalDelayedPopup()-
2724{-
2725 QMenuPrivate * const d = d_func();-
2726-
2727 if (QMenu *menu = d->activeMenu) {-
2728 if (d->activeMenu->menuAction() != d->currentAction)-
2729 d->hideMenu(menu);-
2730 }-
2731-
2732 if (!d->currentAction || !d->currentAction->isEnabled() || !d->currentAction->menu() ||-
2733 !d->currentAction->menu()->isEnabled() || d->currentAction->menu()->isVisible())-
2734 return;-
2735-
2736-
2737 d->activeMenu = d->currentAction->menu();-
2738 d->activeMenu->d_func()->causedPopup.widget = this;-
2739 d->activeMenu->d_func()->causedPopup.action = d->currentAction;-
2740-
2741 int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this);-
2742 const QRect actionRect(d->actionRect(d->currentAction));-
2743 const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top())));-
2744-
2745 d->activeMenu->popup(rightPos);-
2746 d->sloppyState.setSubMenuPopup(actionRect, d->currentAction, d->activeMenu);-
2747-
2748-
2749-
2750-
2751-
2752 if (underMouse()) {-
2753 QEvent leaveEvent(QEvent::Leave);-
2754 QCoreApplication::sendEvent(this, &leaveEvent);-
2755 }-
2756-
2757}-
2758void QMenu::setNoReplayFor(QWidget *noReplayFor)-
2759{-
2760 d_func()->noReplayFor = noReplayFor;-
2761}-
2762-
2763-
2764-
2765QPlatformMenu *QMenu::platformMenu()-
2766{-
2767-
2768 return d_func()->platformMenu;-
2769}-
2770-
2771-
2772-
2773void QMenu::setPlatformMenu(QPlatformMenu *platformMenu)-
2774{-
2775 d_func()->setPlatformMenu(platformMenu);-
2776 d_func()->syncPlatformMenu();-
2777}-
2778bool QMenu::separatorsCollapsible() const-
2779{-
2780 const QMenuPrivate * const d = d_func();-
2781 return d->collapsibleSeparators;-
2782}-
2783-
2784void QMenu::setSeparatorsCollapsible(bool collapse)-
2785{-
2786 QMenuPrivate * const d = d_func();-
2787 if (d->collapsibleSeparators == collapse)-
2788 return;-
2789-
2790 d->collapsibleSeparators = collapse;-
2791 d->itemsDirty = 1;-
2792 if (isVisible()) {-
2793 d->updateActionRects();-
2794 update();-
2795 }-
2796 if (!d->platformMenu.isNull())-
2797 d->platformMenu->syncSeparatorsCollapsible(collapse);-
2798}-
2799bool QMenu::toolTipsVisible() const-
2800{-
2801 const QMenuPrivate * const d = d_func();-
2802 return d->toolTipsVisible;-
2803}-
2804-
2805void QMenu::setToolTipsVisible(bool visible)-
2806{-
2807 QMenuPrivate * const d = d_func();-
2808 if (d->toolTipsVisible == visible)-
2809 return;-
2810-
2811 d->toolTipsVisible = visible;-
2812}-
2813-
2814-
2815-
2816-
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9