widgets/qmenu.cpp

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

Generated by Squish Coco Non-Commercial