Qt 4.8
qmenu.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qmenu.h"
43 
44 #ifndef QT_NO_MENU
45 
46 #include "qdebug.h"
47 #include "qstyle.h"
48 #include "qevent.h"
49 #include "qtimer.h"
50 #include "qlayout.h"
51 #include "qpainter.h"
52 #include "qapplication.h"
53 #include "qdesktopwidget.h"
54 #ifndef QT_NO_ACCESSIBILITY
55 # include "qaccessible.h"
56 #endif
57 #ifndef QT_NO_EFFECTS
58 # include <private/qeffects_p.h>
59 #endif
60 #ifndef QT_NO_WHATSTHIS
61 # include <qwhatsthis.h>
62 #endif
63 
64 #include "qmenu_p.h"
65 #include "qmenubar_p.h"
66 #include "qwidgetaction.h"
67 #include "qtoolbutton.h"
68 #include "qpushbutton.h"
69 #include <private/qpushbutton_p.h>
70 #include <private/qaction_p.h>
71 #include <private/qsoftkeymanager_p.h>
72 #ifdef QT3_SUPPORT
73 #include <qmenudata.h>
74 #endif // QT3_SUPPORT
75 
76 #ifdef Q_WS_X11
77 # include <private/qt_x11_p.h>
78 #endif
79 
80 #if defined(Q_WS_MAC) && !defined(QT_NO_EFFECTS)
81 # include <private/qcore_mac_p.h>
82 # include <private/qt_cocoa_helpers_mac_p.h>
83 #endif
84 
85 #ifdef Q_WS_S60
86 # include "private/qt_s60_p.h"
87 #endif
88 
89 
91 
93 
94 /* QMenu code */
95 // internal class used for the torn off popup
96 class QTornOffMenu : public QMenu
97 {
98  Q_OBJECT
100  {
102  public:
104  tornoff = 1;
105  causedPopup.widget = 0;
106  causedPopup.action = ((QTornOffMenu*)p)->d_func()->causedPopup.action;
107  causedStack = ((QTornOffMenu*)p)->d_func()->calcCausedStack();
108  }
112  };
113 public:
115  {
116  Q_D(QTornOffMenu);
117  // make the torn-off menu a sibling of p (instead of a child)
118  QWidget *parentWidget = d->causedStack.isEmpty() ? p : d->causedStack.last();
119  if (parentWidget->parentWidget())
120  parentWidget = parentWidget->parentWidget();
121  setParent(parentWidget, Qt::Window | Qt::Tool);
125  setEnabled(p->isEnabled());
126  //QObject::connect(this, SIGNAL(triggered(QAction*)), this, SLOT(onTrigger(QAction*)));
127  //QObject::connect(this, SIGNAL(hovered(QAction*)), this, SLOT(onHovered(QAction*)));
128  QList<QAction*> items = p->actions();
129  for(int i = 0; i < items.count(); i++)
130  addAction(items.at(i));
131  }
132  void syncWithMenu(QMenu *menu, QActionEvent *act)
133  {
134  Q_D(QTornOffMenu);
135  if(menu != d->causedMenu)
136  return;
137  if (act->type() == QEvent::ActionAdded) {
138  insertAction(act->before(), act->action());
139  } else if (act->type() == QEvent::ActionRemoved)
140  removeAction(act->action());
141  }
143  {
146  }
147 public slots:
148  void onTrigger(QAction *action) { d_func()->activateAction(action, QAction::Trigger, false); }
149  void onHovered(QAction *action) { d_func()->activateAction(action, QAction::Hover, false); }
150 private:
153 };
154 
155 void QMenuPrivate::init()
156 {
157  Q_Q(QMenu);
158 #ifndef QT_NO_WHATSTHIS
159  q->setAttribute(Qt::WA_CustomWhatsThis);
160 #endif
161  q->setAttribute(Qt::WA_X11NetWmWindowTypePopupMenu);
163  menuAction->d_func()->menu = q;
164  q->setMouseTracking(q->style()->styleHint(QStyle::SH_Menu_MouseTracking, 0, q));
165  if (q->style()->styleHint(QStyle::SH_Menu_Scrollable, 0, q)) {
168  }
169 
170 #ifdef QT_SOFTKEYS_ENABLED
173  selectAction->setPriority(QAction::HighPriority);
174  cancelAction->setPriority(QAction::HighPriority);
175  q->addAction(selectAction);
176  q->addAction(cancelAction);
177 #endif
178 
179 #ifdef Q_WS_S60
180  if (S60->avkonComponentsSupportTransparency) {
181  bool noSystemBackground = q->testAttribute(Qt::WA_NoSystemBackground);
182  q->setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground
183  q->setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute
184  }
185 #endif
186 }
187 
189 {
190  Q_Q(const QMenu);
191  return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));
192 }
193 
194 //Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
196 {
197 #ifdef Q_WS_WIN
198  return QApplication::desktop()->screenGeometry(widget);
199 #elif defined Q_WS_X11
200  if (X11->desktopEnvironment == DE_KDE)
201  return QApplication::desktop()->screenGeometry(widget);
202  else
203  return QApplication::desktop()->availableGeometry(widget);
204 #else
205  return QApplication::desktop()->availableGeometry(widget);
206 #endif
207 }
208 
209 //Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
211 {
212 #ifdef Q_WS_WIN
213  return QApplication::desktop()->screenGeometry(screen);
214 #elif defined Q_WS_X11
215  if (X11->desktopEnvironment == DE_KDE)
216  return QApplication::desktop()->screenGeometry(screen);
217  else
218  return QApplication::desktop()->availableGeometry(screen);
219 #else
220  return QApplication::desktop()->availableGeometry(screen);
221 #endif
222 }
223 
225 {
227  for(QWidget *widget = causedPopup.widget; widget; ) {
228  ret.append(widget);
229  if (QTornOffMenu *qtmenu = qobject_cast<QTornOffMenu*>(widget))
230  ret += qtmenu->d_func()->causedStack;
231  if (QMenu *qmenu = qobject_cast<QMenu*>(widget))
232  widget = qmenu->d_func()->causedPopup.widget;
233  else
234  break;
235  }
236  return ret;
237 }
238 
240 {
241  Q_Q(const QMenu);
243 }
244 
245 void QMenuPrivate::updateActionRects(const QRect &screen) const
246 {
247  Q_Q(const QMenu);
248  if (!itemsDirty)
249  return;
250 
251  q->ensurePolished();
252 
253  //let's reinitialize the buffer
256 
257  int lastVisibleAction = getLastVisibleAction();
258 
259  int max_column_width = 0,
260  dh = screen.height(),
261  y = 0;
262  QStyle *style = q->style();
263  QStyleOption opt;
264  opt.init(q);
265  const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, &opt, q),
266  vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, &opt, q),
267  icone = style->pixelMetric(QStyle::PM_SmallIconSize, &opt, q);
268  const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, q);
269  const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q);
270  const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0;
271 
272  //for compatibility now - will have to refactor this away
273  tabWidth = 0;
274  maxIconWidth = 0;
275  hasCheckableItems = false;
276  ncols = 1;
277  sloppyAction = 0;
278 
279  for (int i = 0; i < actions.count(); ++i) {
280  QAction *action = actions.at(i);
281  if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action))
282  continue;
283  //..and some members
284  hasCheckableItems |= action->isCheckable();
285  QIcon is = action->icon();
286  if (!is.isNull()) {
287  maxIconWidth = qMax<uint>(maxIconWidth, icone + 4);
288  }
289  }
290 
291  //calculate size
292  QFontMetrics qfm = q->fontMetrics();
293  bool previousWasSeparator = true; // this is true to allow removing the leading separators
294  for(int i = 0; i <= lastVisibleAction; i++) {
295  QAction *action = actions.at(i);
296 
297  if (!action->isVisible() ||
298  (collapsibleSeparators && previousWasSeparator && action->isSeparator()))
299  continue; // we continue, this action will get an empty QRect
300 
301  previousWasSeparator = action->isSeparator();
302 
303  //let the style modify the above size..
305  q->initStyleOption(&opt, action);
306  const QFontMetrics &fm = opt.fontMetrics;
307 
308  QSize sz;
309  if (QWidget *w = widgetItems.value(action)) {
310  sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize());
311  } else {
312  //calc what I think the size is..
313  if (action->isSeparator()) {
314  sz = QSize(2, 2);
315  } else {
316  QString s = action->text();
317  int t = s.indexOf(QLatin1Char('\t'));
318  if (t != -1) {
319  tabWidth = qMax(int(tabWidth), qfm.width(s.mid(t+1)));
320  s = s.left(t);
321  #ifndef QT_NO_SHORTCUT
322  } else {
323  QKeySequence seq = action->shortcut();
324  if (!seq.isEmpty())
325  tabWidth = qMax(int(tabWidth), qfm.width(seq));
326  #endif
327  }
329  sz.setHeight(qMax(fm.height(), qfm.height()));
330 
331  QIcon is = action->icon();
332  if (!is.isNull()) {
333  QSize is_sz = QSize(icone, icone);
334  if (is_sz.height() > sz.height())
335  sz.setHeight(is_sz.height());
336  }
337  }
338  sz = style->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, q);
339  }
340 
341 
342  if (!sz.isEmpty()) {
343  max_column_width = qMax(max_column_width, sz.width());
344  //wrapping
345  if (!scroll &&
346  y+sz.height()+vmargin > dh - (deskFw * 2)) {
347  ncols++;
348  y = vmargin;
349  }
350  y += sz.height();
351  //update the item
352  actionRects[i] = QRect(0, 0, sz.width(), sz.height());
353  }
354  }
355 
356  max_column_width += tabWidth; //finally add in the tab width
357  const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width();
358  const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin));
359  max_column_width = qMax(min_column_width, max_column_width);
360 
361  //calculate position
362  const int base_y = vmargin + fw + topmargin +
363  (scroll ? scroll->scrollOffset : 0) +
364  tearoffHeight;
365  int x = hmargin + fw + leftmargin;
366  y = base_y;
367 
368  for(int i = 0; i < actions.count(); i++) {
369  QRect &rect = actionRects[i];
370  if (rect.isNull())
371  continue;
372  if (!scroll &&
373  y+rect.height() > dh - deskFw * 2) {
374  x += max_column_width + hmargin;
375  y = base_y;
376  }
377  rect.translate(x, y); //move
378  rect.setWidth(max_column_width); //uniform width
379 
380  //we need to update the widgets geometry
381  if (QWidget *widget = widgetItems.value(actions.at(i))) {
382  widget->setGeometry(rect);
384  }
385 
386  y += rect.height();
387  }
388  itemsDirty = 0;
389 }
390 
392 {
393  Q_Q(QMenu);
394  QSize ret = screen.size();
395  itemsDirty = true;
396  updateActionRects(screen);
397  const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
399  return ret;
400 }
401 
403 {
404  //let's try to get the last visible action
405  int lastVisibleAction = actions.count() - 1;
406  for (;lastVisibleAction >= 0; --lastVisibleAction) {
407  const QAction *action = actions.at(lastVisibleAction);
408  if (action->isVisible()) {
409  //removing trailing separators
410  if (action->isSeparator() && collapsibleSeparators)
411  continue;
412  break;
413  }
414  }
415  return lastVisibleAction;
416 }
417 
418 
420 {
421  int index = actions.indexOf(act);
422  if (index == -1)
423  return QRect();
424 
426 
427  //we found the action
428  return actionRects.at(index);
429 }
430 
431 #if defined(Q_WS_MAC)
432 static const qreal MenuFadeTimeInSec = 0.150;
433 #endif
434 
436 {
437  Q_Q(QMenu);
438  bool fadeMenus = q->style()->styleHint(QStyle::SH_Menu_FadeOutOnHide);
439  if (!tornoff) {
440  QWidget *caused = causedPopup.widget;
441  hideMenu(q); //hide after getting causedPopup
442  while(caused) {
443 #ifndef QT_NO_MENUBAR
444  if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
445  mb->d_func()->setCurrentAction(0);
446  mb->d_func()->setKeyboardMode(false);
447  caused = 0;
448  } else
449 #endif
450  if (QMenu *m = qobject_cast<QMenu*>(caused)) {
451  caused = m->d_func()->causedPopup.widget;
452  if (!m->d_func()->tornoff)
453  hideMenu(m, fadeMenus);
454  if (!fadeMenus) // Mac doesn't clear the action until after hidden.
455  m->d_func()->setCurrentAction(0);
456  } else { caused = 0;
457  }
458  }
459 #if defined(Q_WS_MAC)
460  if (fadeMenus) {
462  QTimer::singleShot(int(MenuFadeTimeInSec * 1000), &eventLoop, SLOT(quit()));
464  eventLoop.exec();
465  }
466 #endif
467  }
468  setCurrentAction(0);
469 }
470 
471 void QMenuPrivate::hideMenu(QMenu *menu, bool justRegister)
472 {
473  if (!menu)
474  return;
475 #if !defined(QT_NO_EFFECTS)
476  menu->blockSignals(true);
477  aboutToHide = true;
478  // Flash item which is about to trigger (if any).
481  && menu->actions().contains(currentAction)) {
484 
485  menu->setActiveAction(0);
486  QTimer::singleShot(60, &eventLoop, SLOT(quit()));
487  eventLoop.exec();
488 
489  // Select and wait 20 ms.
490  menu->setActiveAction(activeAction);
491  QTimer::singleShot(20, &eventLoop, SLOT(quit()));
492  eventLoop.exec();
493  }
494 
495  // Fade out.
497  // ### Qt 4.4:
498  // Should be something like: q->transitionWindow(Qt::FadeOutTransition, MenuFadeTimeInSec);
499  // Hopefully we'll integrate qt/research/windowtransitions into main before 4.4.
500  // Talk to Richard, Trenton or Bjoern.
501 #if defined(Q_WS_MAC)
502  if (justRegister) {
505  } else {
507  }
508 
509 #endif // Q_WS_MAC
510  }
511  aboutToHide = false;
512  menu->blockSignals(false);
513 #endif // QT_NO_EFFECTS
514  if (!justRegister)
515  menu->close();
516 }
517 
518 void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst)
519 {
520  Q_Q(QMenu);
521  if (action && action->isEnabled()) {
522  if (!delay)
523  q->internalDelayedPopup();
524  else if (!menuDelayTimer.isActive() && (!action->menu() || !action->menu()->isVisible()))
525  menuDelayTimer.start(delay, q);
526  if (activateFirst && action->menu())
527  action->menu()->d_func()->setFirstActionActive();
528  } else if (QMenu *menu = activeMenu) { //hide the current item
529  activeMenu = 0;
530  hideMenu(menu);
531  }
532 }
533 
535 {
536  Q_Q(QMenu);
537  QAction *current = currentAction;
538  if(current && (!current->isEnabled() || current->menu() || current->isSeparator()))
539  current = 0;
540  for(QWidget *caused = q; caused;) {
541  if (QMenu *m = qobject_cast<QMenu*>(caused)) {
542  caused = m->d_func()->causedPopup.widget;
543  if (m->d_func()->eventLoop)
544  m->d_func()->syncAction = current; // synchronous operation
545  } else {
546  break;
547  }
548  }
549 }
550 
551 
553 {
554  Q_Q(QMenu);
556  for(int i = 0, saccum = 0; i < actions.count(); i++) {
557  const QRect &rect = actionRects.at(i);
558  if (rect.isNull())
559  continue;
561  saccum -= rect.height();
562  if (saccum > scroll->scrollOffset - scrollerHeight())
563  continue;
564  }
565  QAction *act = actions.at(i);
566  if (!act->isSeparator() &&
567  (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
568  || act->isEnabled())) {
569  setCurrentAction(act);
570  break;
571  }
572  }
573 }
574 
575 // popup == -1 means do not popup, 0 means immediately, others mean use a timer
576 void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason reason, bool activateFirst)
577 {
578  Q_Q(QMenu);
579  tearoffHighlighted = 0;
580  // Reselect the currently active action in case mouse moved over other menu items when
581  // moving from sub menu action to sub menu (QTBUG-20094).
582  if (reason != SelectedFromKeyboard && action == currentAction && !(action && action->menu() && action->menu() != activeMenu)) {
583  if (QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) {
584  if (causedPopup.action && menu->d_func()->activeMenu == q)
585  menu->d_func()->setCurrentAction(causedPopup.action, 0, reason, false);
586  }
587  return;
588  }
589 
590  if (currentAction)
591  q->update(actionRect(currentAction));
592 
593  sloppyAction = 0;
594  if (!sloppyRegion.isEmpty())
595  sloppyRegion = QRegion();
596  QMenu *hideActiveMenu = activeMenu;
597 #ifndef QT_NO_STATUSTIP
598  QAction *previousAction = currentAction;
599 #endif
600 #ifdef QT3_SUPPORT
601  emitHighlighted = action;
602 #endif
603 
604  currentAction = action;
605  if (action) {
606  if (!action->isSeparator()) {
608  if (popup != -1) {
609  hideActiveMenu = 0; //will be done "later"
610  // if the menu is visible then activate the required action,
611  // otherwise we just mark the action as currentAction
612  // and activate it when the menu will be popuped.
613  if (q->isVisible())
614  popupAction(currentAction, popup, activateFirst);
615  }
616  q->update(actionRect(action));
617 
618  if (reason == SelectedFromKeyboard) {
619  QWidget *widget = widgetItems.value(action);
620  if (widget) {
621  if (widget->focusPolicy() != Qt::NoFocus)
622  widget->setFocus(Qt::TabFocusReason);
623  } else {
624  //when the action has no QWidget, the QMenu itself should
625  // get the focus
626  // Since the menu is a pop-up, it uses the popup reason.
627  if (!q->hasFocus()) {
628  q->setFocus(Qt::PopupFocusReason);
629  }
630  }
631  }
632  } else { //action is a separator
633  if (popup != -1)
634  hideActiveMenu = 0; //will be done "later"
635  }
636 #ifndef QT_NO_STATUSTIP
637  } else if (previousAction) {
638  previousAction->d_func()->showStatusText(topCausedWidget(), QString());
639 #endif
640  }
641  if (hideActiveMenu) {
642  activeMenu = 0;
643 #ifndef QT_NO_EFFECTS
644  // kill any running effect
645  qFadeEffect(0);
646  qScrollEffect(0);
647 #endif
648  hideMenu(hideActiveMenu);
649  }
650 }
651 
652 //return the top causedPopup.widget that is not a QMenu
654 {
655  QWidget* top = causedPopup.widget;
656  while (QMenu* m = qobject_cast<QMenu *>(top))
657  top = m->d_func()->causedPopup.widget;
658  return top;
659 }
660 
662 {
663  if (!q_func()->rect().contains(p)) //sanity check
664  return 0;
665 
666  for(int i = 0; i < actionRects.count(); i++) {
667  if (actionRects.at(i).contains(p))
668  return actions.at(i);
669  }
670  return 0;
671 }
672 
674 {
675  Q_Q(QMenu);
677  if (a) {
678  menuAction = a;
680  } else { //we revert back to the default action created by the QMenu itself
682  }
683 }
684 
686 {
688 }
689 
690 
692 {
693  Q_Q(QMenu);
694  //we need to mimic the cause of the popup's layout direction
695  //to allow setting it on a mainwindow for example
696  //we call setLayoutDirection_helper to not overwrite a user-defined value
697  if (!q->testAttribute(Qt::WA_SetLayoutDirection)) {
698  if (QWidget *w = causedPopup.widget)
699  setLayoutDirection_helper(w->layoutDirection());
700  else if (QWidget *w = q->parentWidget())
701  setLayoutDirection_helper(w->layoutDirection());
702  else
704  }
705 }
706 
707 
712 {
713  return d_func()->menuAction;
714 }
715 
727 QString QMenu::title() const
728 {
729  return d_func()->menuAction->text();
730 }
731 
733 {
734  d_func()->menuAction->setText(text);
735 }
736 
749 QIcon QMenu::icon() const
750 {
751  return d_func()->menuAction->icon();
752 }
753 
755 {
756  d_func()->menuAction->setIcon(icon);
757 }
758 
759 
760 //actually performs the scrolling
762 {
763  Q_Q(QMenu);
764  if (!scroll || !scroll->scrollFlags)
765  return;
767  int newOffset = 0;
768  const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
769  const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
770  const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
771  const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
772 
773  if (location == QMenuScroller::ScrollTop) {
774  for(int i = 0, saccum = 0; i < actions.count(); i++) {
775  if (actions.at(i) == action) {
776  newOffset = topScroll - saccum;
777  break;
778  }
779  saccum += actionRects.at(i).height();
780  }
781  } else {
782  for(int i = 0, saccum = 0; i < actions.count(); i++) {
783  saccum += actionRects.at(i).height();
784  if (actions.at(i) == action) {
785  if (location == QMenuScroller::ScrollCenter)
786  newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll);
787  else
788  newOffset = (q->height() - botScroll) - saccum;
789  break;
790  }
791  }
792  if(newOffset)
793  newOffset -= fw * 2;
794  }
795 
796  //figure out which scroll flags
797  uint newScrollFlags = QMenuScroller::ScrollNone;
798  if (newOffset < 0) //easy and cheap one
799  newScrollFlags |= QMenuScroller::ScrollUp;
800  int saccum = newOffset;
801  for(int i = 0; i < actionRects.count(); i++) {
802  saccum += actionRects.at(i).height();
803  if (saccum > q->height()) {
804  newScrollFlags |= QMenuScroller::ScrollDown;
805  break;
806  }
807  }
808 
809  if (!(newScrollFlags & QMenuScroller::ScrollDown) && (scroll->scrollFlags & QMenuScroller::ScrollDown)) {
810  newOffset = q->height() - (saccum - newOffset) - fw*2 - vmargin; //last item at bottom
811  }
812 
813  if (!(newScrollFlags & QMenuScroller::ScrollUp) && (scroll->scrollFlags & QMenuScroller::ScrollUp)) {
814  newOffset = 0; //first item at top
815  }
816 
817  if (newScrollFlags & QMenuScroller::ScrollUp)
818  newOffset -= vmargin;
819 
820  QRect screen = popupGeometry(q);
821  const int desktopFrame = q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q);
822  if (q->height() < screen.height()-(desktopFrame*2)-1) {
823  QRect geom = q->geometry();
824  if (newOffset > scroll->scrollOffset && (scroll->scrollFlags & newScrollFlags & QMenuScroller::ScrollUp)) { //scroll up
825  const int newHeight = geom.height()-(newOffset-scroll->scrollOffset);
826  if(newHeight > geom.height())
827  geom.setHeight(newHeight);
828  } else if(scroll->scrollFlags & newScrollFlags & QMenuScroller::ScrollDown) {
829  int newTop = geom.top() + (newOffset-scroll->scrollOffset);
830  if (newTop < desktopFrame+screen.top())
831  newTop = desktopFrame+screen.top();
832  if (newTop < geom.top()) {
833  geom.setTop(newTop);
834  newOffset = 0;
835  newScrollFlags &= ~QMenuScroller::ScrollUp;
836  }
837  }
838  if (geom.bottom() > screen.bottom() - desktopFrame)
839  geom.setBottom(screen.bottom() - desktopFrame);
840  if (geom.top() < desktopFrame+screen.top())
841  geom.setTop(desktopFrame+screen.top());
842  if (geom != q->geometry()) {
843 #if 0
844  if (newScrollFlags & QMenuScroller::ScrollDown &&
845  q->geometry().top() - geom.top() >= -newOffset)
846  newScrollFlags &= ~QMenuScroller::ScrollDown;
847 #endif
848  q->setGeometry(geom);
849  }
850  }
851 
852  //actually update flags
853  const int delta = qMin(0, newOffset) - scroll->scrollOffset; //make sure the new offset is always negative
854  if (!itemsDirty && delta) {
855  //we've scrolled so we need to update the action rects
856  for (int i = 0; i < actionRects.count(); ++i) {
857  QRect &current = actionRects[i];
858  current.moveTop(current.top() + delta);
859 
860  //we need to update the widgets geometry
861  if (QWidget *w = widgetItems.value(actions.at(i)))
862  w->setGeometry(current);
863  }
864  }
865  scroll->scrollOffset += delta;
866  scroll->scrollFlags = newScrollFlags;
867  if (active)
868  setCurrentAction(action);
869 
870  q->update(); //issue an update so we see all the new state..
871 }
872 
874 {
875  Q_Q(QMenu);
877  if(location == QMenuScroller::ScrollBottom) {
878  for(int i = actions.size()-1; i >= 0; --i) {
879  QAction *act = actions.at(i);
880  if (actionRects.at(i).isNull())
881  continue;
882  if (!act->isSeparator() &&
883  (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
884  || act->isEnabled())) {
887  else if(active)
889  break;
890  }
891  }
892  } else if(location == QMenuScroller::ScrollTop) {
893  for(int i = 0; i < actions.size(); ++i) {
894  QAction *act = actions.at(i);
895  if (actionRects.at(i).isNull())
896  continue;
897  if (!act->isSeparator() &&
898  (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
899  || act->isEnabled())) {
902  else if(active)
904  break;
905  }
906  }
907  }
908 }
909 
910 //only directional
912 {
913  Q_Q(QMenu);
914  if (!scroll || !(scroll->scrollFlags & direction)) //not really possible...
915  return;
917  const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
918  const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
919  const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
920  const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
921  const int offset = topScroll ? topScroll-vmargin : 0;
922  if (direction == QMenuScroller::ScrollUp) {
923  for(int i = 0, saccum = 0; i < actions.count(); i++) {
924  saccum -= actionRects.at(i).height();
925  if (saccum <= scroll->scrollOffset-offset) {
927  break;
928  }
929  }
930  } else if (direction == QMenuScroller::ScrollDown) {
931  bool scrolled = false;
932  for(int i = 0, saccum = 0; i < actions.count(); i++) {
933  const int iHeight = actionRects.at(i).height();
934  saccum -= iHeight;
935  if (saccum <= scroll->scrollOffset-offset) {
936  const int scrollerArea = q->height() - botScroll - fw*2;
937  int visible = (scroll->scrollOffset-offset) - saccum;
938  for(i++ ; i < actions.count(); i++) {
939  visible += actionRects.at(i).height();
940  if (visible > scrollerArea - topScroll) {
941  scrolled = true;
943  break;
944  }
945  }
946  break;
947  }
948  }
949  if(!scrolled) {
950  scroll->scrollFlags &= ~QMenuScroller::ScrollDown;
951  q->update();
952  }
953  }
954 }
955 
956 /* This is poor-mans eventfilters. This avoids the use of
957  eventFilter (which can be nasty for users of QMenuBar's). */
959 {
960  Q_Q(QMenu);
961  QPoint pos = q->mapFromGlobal(e->globalPos());
962  if (scroll && !activeMenu) { //let the scroller "steal" the event
963  bool isScroll = false;
964  if (pos.x() >= 0 && pos.x() < q->width()) {
965  for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) {
966  if (scroll->scrollFlags & dir) {
967  if (dir == QMenuScroller::ScrollUp)
968  isScroll = (pos.y() <= scrollerHeight());
969  else if (dir == QMenuScroller::ScrollDown)
970  isScroll = (pos.y() >= q->height() - scrollerHeight());
971  if (isScroll) {
972  scroll->scrollDirection = dir;
973  break;
974  }
975  }
976  }
977  }
978  if (isScroll) {
979  scroll->scrollTimer.start(50, q);
980  return true;
981  } else {
983  }
984  }
985 
986  if (tearoff) { //let the tear off thingie "steal" the event..
987  QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q));
989  tearRect.translate(0, scrollerHeight());
990  q->update(tearRect);
991  if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) {
992  setCurrentAction(0);
993  tearoffHighlighted = 1;
994  if (e->type() == QEvent::MouseButtonRelease) {
995  if (!tornPopup)
996  tornPopup = new QTornOffMenu(q);
997  tornPopup->setGeometry(q->geometry());
998  tornPopup->show();
999  hideUpToMenuBar();
1000  }
1001  return true;
1002  }
1003  tearoffHighlighted = 0;
1004  }
1005 
1006  if (q->frameGeometry().contains(e->globalPos())) //otherwise if the event is in our rect we want it..
1007  return false;
1008 
1009  for(QWidget *caused = causedPopup.widget; caused;) {
1010  bool passOnEvent = false;
1011  QWidget *next_widget = 0;
1012  QPoint cpos = caused->mapFromGlobal(e->globalPos());
1013 #ifndef QT_NO_MENUBAR
1014  if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
1015  passOnEvent = mb->rect().contains(cpos);
1016  } else
1017 #endif
1018  if (QMenu *m = qobject_cast<QMenu*>(caused)) {
1019  passOnEvent = m->rect().contains(cpos);
1020  next_widget = m->d_func()->causedPopup.widget;
1021  }
1022  if (passOnEvent) {
1023  if(e->type() != QEvent::MouseButtonRelease || mouseDown == caused) {
1024  QMouseEvent new_e(e->type(), cpos, e->button(), e->buttons(), e->modifiers());
1025  QApplication::sendEvent(caused, &new_e);
1026  return true;
1027  }
1028  }
1029  if (!next_widget)
1030  break;
1031  caused = next_widget;
1032  }
1033  return false;
1034 }
1035 
1037 {
1039 #ifdef QT3_SUPPORT
1040  const int actionId = q_func()->findIdForAction(action);
1041 #endif
1042  if(self)
1043  action->activate(action_e);
1044 
1045  for(int i = 0; i < causedStack.size(); ++i) {
1047  if (!widget)
1048  continue;
1049  //fire
1050  if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
1051  widget = qmenu->d_func()->causedPopup.widget;
1052  if (action_e == QAction::Trigger) {
1053  emit qmenu->triggered(action);
1054  } else if (action_e == QAction::Hover) {
1055  emit qmenu->hovered(action);
1056 #ifdef QT3_SUPPORT
1057  if (emitHighlighted) {
1058  emit qmenu->highlighted(actionId);
1059  emitHighlighted = false;
1060  }
1061 #endif
1062  }
1063 #ifndef QT_NO_MENUBAR
1064  } else if (QMenuBar *qmenubar = qobject_cast<QMenuBar*>(widget)) {
1065  if (action_e == QAction::Trigger) {
1066  emit qmenubar->triggered(action);
1067 #ifdef QT3_SUPPORT
1068  emit qmenubar->activated(actionId);
1069 #endif
1070  } else if (action_e == QAction::Hover) {
1071  emit qmenubar->hovered(action);
1072 #ifdef QT3_SUPPORT
1073  if (emitHighlighted) {
1074  emit qmenubar->highlighted(actionId);
1075  emitHighlighted = false;
1076  }
1077 #endif
1078  }
1079  break; //nothing more..
1080 #endif
1081  }
1082  }
1083 }
1084 
1086 {
1087  Q_Q(QMenu);
1088 #ifndef QT_NO_WHATSTHIS
1089  bool inWhatsThisMode = QWhatsThis::inWhatsThisMode();
1090 #endif
1091  if (!action || !q->isEnabled()
1092  || (action_e == QAction::Trigger
1093 #ifndef QT_NO_WHATSTHIS
1094  && !inWhatsThisMode
1095 #endif
1096  && (action->isSeparator() ||!action->isEnabled())))
1097  return;
1098 
1099  /* I have to save the caused stack here because it will be undone after popup execution (ie in the hide).
1100  Then I iterate over the list to actually send the events. --Sam
1101  */
1103  if (action_e == QAction::Trigger) {
1104 #ifndef QT_NO_WHATSTHIS
1105  if (!inWhatsThisMode)
1106  actionAboutToTrigger = action;
1107 #endif
1108 
1109  if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
1110  hideUpToMenuBar();
1111  } else {
1113  if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
1114  if(qmenu == q)
1115  hideUpToMenuBar();
1116  widget = qmenu->d_func()->causedPopup.widget;
1117  } else {
1118  break;
1119  }
1120  }
1121  }
1122 
1123 #ifndef QT_NO_WHATSTHIS
1124  if (inWhatsThisMode) {
1125  QString s = action->whatsThis();
1126  if (s.isEmpty())
1127  s = whatsThis;
1128  QWhatsThis::showText(q->mapToGlobal(actionRect(action).center()), s, q);
1129  return;
1130  }
1131 #endif
1132  }
1133 
1134 
1135  activateCausedStack(causedStack, action, action_e, self);
1136 
1137 
1138  if (action_e == QAction::Hover) {
1139 #ifndef QT_NO_ACCESSIBILITY
1140  if (QAccessible::isActive()) {
1141  int actionIndex = indexOf(action) + 1;
1144  }
1145 #endif
1146  action->showStatusText(topCausedWidget());
1147  } else {
1149  }
1150 }
1151 
1153 {
1154  Q_Q(QMenu);
1155  if (QAction *action = qobject_cast<QAction *>(q->sender())) {
1156  QWeakPointer<QAction> actionGuard = action;
1157 #ifdef QT3_SUPPORT
1158  //we store it here because the action might be deleted/changed by connected slots
1159  const int id = q->findIdForAction(action);
1160 #endif
1161  emit q->triggered(action);
1162 #ifdef QT3_SUPPORT
1163  emit q->activated(id);
1164 #endif
1165 
1166  if (!activationRecursionGuard && actionGuard) {
1167  //in case the action has not been activated by the mouse
1168  //we check the parent hierarchy
1169  QList< QPointer<QWidget> > list;
1170  for(QWidget *widget = q->parentWidget(); widget; ) {
1171  if (qobject_cast<QMenu*>(widget)
1172 #ifndef QT_NO_MENUBAR
1174 #endif
1175  ) {
1176  list.append(widget);
1177  widget = widget->parentWidget();
1178  } else {
1179  break;
1180  }
1181  }
1182  activateCausedStack(list, action, QAction::Trigger, false);
1183  }
1184  }
1185 }
1186 
1188 {
1189  Q_Q(QMenu);
1190  if (QAction * action = qobject_cast<QAction *>(q->sender())) {
1191 #ifdef QT3_SUPPORT
1192  //we store it here because the action might be deleted/changed by connected slots
1193  const int id = q->findIdForAction(action);
1194 #endif
1195  emit q->hovered(action);
1196 #ifdef QT3_SUPPORT
1197  if (emitHighlighted) {
1198  emit q->highlighted(id);
1199  emitHighlighted = false;
1200  }
1201 #endif
1202  }
1203 }
1204 
1205 bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
1206 {
1207  //determines if the mouse has moved (ie its initial position has
1208  //changed by more than QApplication::startDragDistance()
1209  //or if there were at least 6 mouse motions)
1210  return motions > 6 ||
1211  QApplication::startDragDistance() < (mousePopupPos - globalPos).manhattanLength();
1212 }
1213 
1214 
1222 void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const
1223 {
1224  if (!option || !action)
1225  return;
1226 
1227  Q_D(const QMenu);
1228  option->initFrom(this);
1229  option->palette = palette();
1230  option->state = QStyle::State_None;
1231 
1232  if (window()->isActiveWindow())
1233  option->state |= QStyle::State_Active;
1234  if (isEnabled() && action->isEnabled()
1235  && (!action->menu() || action->menu()->isEnabled()))
1236  option->state |= QStyle::State_Enabled;
1237  else
1239 
1240  option->font = action->font().resolve(font());
1241  option->fontMetrics = QFontMetrics(option->font);
1242 
1243  if (d->currentAction && d->currentAction == action && !d->currentAction->isSeparator()) {
1244  option->state |= QStyle::State_Selected
1245  | (d->mouseDown ? QStyle::State_Sunken : QStyle::State_None);
1246  }
1247 
1248  option->menuHasCheckableItems = d->hasCheckableItems;
1249  if (!action->isCheckable()) {
1251  } else {
1252  option->checkType = (action->actionGroup() && action->actionGroup()->isExclusive())
1254  option->checked = action->isChecked();
1255  }
1256  if (action->menu())
1258  else if (action->isSeparator())
1260  else if (d->defaultAction == action)
1262  else
1264  if (action->isIconVisibleInMenu())
1265  option->icon = action->icon();
1266  QString textAndAccel = action->text();
1267 #ifndef QT_NO_SHORTCUT
1268  if (textAndAccel.indexOf(QLatin1Char('\t')) == -1) {
1269  QKeySequence seq = action->shortcut();
1270  if (!seq.isEmpty())
1271  textAndAccel += QLatin1Char('\t') + QString(seq);
1272  }
1273 #endif
1274  option->text = textAndAccel;
1275  option->tabWidth = d->tabWidth;
1276  option->maxIconWidth = d->maxIconWidth;
1277  option->menuRect = rect();
1278 }
1279 
1387  : QWidget(*new QMenuPrivate, parent, Qt::Popup)
1388 {
1389  Q_D(QMenu);
1390  d->init();
1391 }
1392 
1403  : QWidget(*new QMenuPrivate, parent, Qt::Popup)
1404 {
1405  Q_D(QMenu);
1406  d->init();
1407  d->menuAction->setText(title);
1408 }
1409 
1413  : QWidget(dd, parent, Qt::Popup)
1414 {
1415  Q_D(QMenu);
1416  d->init();
1417 }
1418 
1423 {
1424  Q_D(QMenu);
1425  if (!d->widgetItems.isEmpty()) { // avoid detach on shared null hash
1426  QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin();
1427  for (; it != d->widgetItems.end(); ++it) {
1428  if (QWidget *widget = it.value()) {
1429  QWidgetAction *action = static_cast<QWidgetAction *>(it.key());
1430  action->releaseWidget(widget);
1431  *it = 0;
1432  }
1433  }
1434  }
1435 
1436  if (d->eventLoop)
1437  d->eventLoop->exit();
1438  hideTearOffMenu();
1439 }
1440 
1454 {
1455  QAction *ret = new QAction(text, this);
1456  addAction(ret);
1457  return ret;
1458 }
1459 
1473 {
1474  QAction *ret = new QAction(icon, text, this);
1475  addAction(ret);
1476  return ret;
1477 }
1478 
1493 QAction *QMenu::addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut)
1494 {
1495  QAction *action = new QAction(text, this);
1496 #ifdef QT_NO_SHORTCUT
1497  Q_UNUSED(shortcut);
1498 #else
1499  action->setShortcut(shortcut);
1500 #endif
1501  QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
1502  addAction(action);
1503  return action;
1504 }
1505 
1520 QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver,
1521  const char* member, const QKeySequence &shortcut)
1522 {
1523  QAction *action = new QAction(icon, text, this);
1524 #ifdef QT_NO_SHORTCUT
1525  Q_UNUSED(shortcut);
1526 #else
1527  action->setShortcut(shortcut);
1528 #endif
1529  QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
1530  addAction(action);
1531  return action;
1532 }
1533 
1542 {
1543  QAction *action = menu->menuAction();
1544  addAction(action);
1545  return action;
1546 }
1547 
1555 {
1556  QMenu *menu = new QMenu(title, this);
1557  addAction(menu->menuAction());
1558  return menu;
1559 }
1560 
1568 {
1569  QMenu *menu = new QMenu(title, this);
1570  menu->setIcon(icon);
1571  addAction(menu->menuAction());
1572  return menu;
1573 }
1574 
1584 {
1585  QAction *action = new QAction(this);
1586  action->setSeparator(true);
1587  addAction(action);
1588  return action;
1589 }
1590 
1598 {
1599  QAction *action = menu->menuAction();
1600  insertAction(before, action);
1601  return action;
1602 }
1603 
1613 {
1614  QAction *action = new QAction(this);
1615  action->setSeparator(true);
1616  insertAction(before, action);
1617  return action;
1618 }
1619 
1628 {
1629  d_func()->defaultAction = act;
1630 }
1631 
1638 {
1639  return d_func()->defaultAction;
1640 }
1641 
1659 {
1660  Q_D(QMenu);
1661  if (d->tearoff == b)
1662  return;
1663  if (!b)
1664  hideTearOffMenu();
1665  d->tearoff = b;
1666 
1667  d->itemsDirty = true;
1668  if (isVisible())
1669  resize(sizeHint());
1670 }
1671 
1673 {
1674  return d_func()->tearoff;
1675 }
1676 
1685 {
1686  if (d_func()->tornPopup)
1687  return d_func()->tornPopup->isVisible();
1688  return false;
1689 }
1690 
1698 {
1699  if (QWidget *w = d_func()->tornPopup)
1700  w->close();
1701 }
1702 
1703 
1708 {
1709  Q_D(QMenu);
1710  d->setCurrentAction(act, 0);
1711  if (d->scroll)
1712  d->scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollCenter);
1713 }
1714 
1715 
1721 {
1722  return d_func()->currentAction;
1723 }
1724 
1737 bool QMenu::isEmpty() const
1738 {
1739  bool ret = true;
1740  for(int i = 0; ret && i < actions().count(); ++i) {
1741  const QAction *action = actions().at(i);
1742  if (!action->isSeparator() && action->isVisible()) {
1743  ret = false;
1744  }
1745  }
1746  return ret;
1747 }
1748 
1756 {
1757  QList<QAction*> acts = actions();
1758 
1759  for(int i = 0; i < acts.size(); i++) {
1760 #ifdef QT_SOFTKEYS_ENABLED
1761  Q_D(QMenu);
1762  // Lets not touch to our internal softkey actions
1763  if(acts[i] == d->selectAction || acts[i] == d->cancelAction)
1764  continue;
1765 #endif
1766  removeAction(acts[i]);
1767  if (acts[i]->parent() == this && acts[i]->d_func()->widgets.isEmpty())
1768  delete acts[i];
1769  }
1770 }
1771 
1780 {
1781  return d_func()->ncols;
1782 }
1783 
1787 QAction *QMenu::actionAt(const QPoint &pt) const
1788 {
1789  if (QAction *ret = d_func()->actionAt(pt))
1790  return ret;
1791  return 0;
1792 }
1793 
1798 {
1799  return d_func()->actionRect(act);
1800 }
1801 
1806 {
1807  Q_D(const QMenu);
1808  d->updateActionRects();
1809 
1810  QSize s;
1811  for (int i = 0; i < d->actionRects.count(); ++i) {
1812  const QRect &rect = d->actionRects.at(i);
1813  if (rect.isNull())
1814  continue;
1815  if (rect.bottom() >= s.height())
1816  s.setHeight(rect.y() + rect.height());
1817  if (rect.right() >= s.width())
1818  s.setWidth(rect.x() + rect.width());
1819  }
1820  // Note that the action rects calculated above already include
1821  // the top and left margins, so we only need to add margins for
1822  // the bottom and right.
1823  QStyleOption opt(0);
1824  opt.init(this);
1825  const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this);
1826  s.rwidth() += style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this) + fw + d->rightmargin;
1827  s.rheight() += style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, this) + fw + d->bottommargin;
1828 
1829  return style()->sizeFromContents(QStyle::CT_Menu, &opt,
1831 }
1832 
1847 void QMenu::popup(const QPoint &p, QAction *atAction)
1848 {
1849  Q_D(QMenu);
1850 #ifndef Q_OS_SYMBIAN
1851  if (d->scroll) { // reset scroll state from last popup
1852  if (d->scroll->scrollOffset)
1853  d->itemsDirty = 1; // sizeHint will be incorrect if there is previous scroll
1854  d->scroll->scrollOffset = 0;
1855  d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
1856  }
1857 #endif
1858  d->tearoffHighlighted = 0;
1859  d->motions = 0;
1860  d->doChildEffects = true;
1861  d->updateLayoutDirection();
1862 
1863 #ifndef QT_NO_MENUBAR
1864  // if this menu is part of a chain attached to a QMenuBar, set the
1865  // _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type
1866  setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(d->topCausedWidget()) != 0);
1867 #endif
1868 
1869  ensurePolished(); // Get the right font
1870  emit aboutToShow();
1871  const bool actionListChanged = d->itemsDirty;
1872  d->updateActionRects();
1873  QPoint pos;
1874  QPushButton *causedButton = qobject_cast<QPushButton*>(d->causedPopup.widget);
1875  if (actionListChanged && causedButton)
1876  pos = QPushButtonPrivate::get(causedButton)->adjustedMenuPosition();
1877  else
1878  pos = p;
1879 
1880  QSize size = sizeHint();
1881  QRect screen;
1882 #ifndef QT_NO_GRAPHICSVIEW
1883  bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this);
1884  if (isEmbedded)
1885  screen = d->popupGeometry(this);
1886  else
1887 #endif
1888  screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));
1889  const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this);
1890  bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen);
1891  if (!d->scroll) {
1892  // if the screens have very different geometries and the menu is too big, we have to recalculate
1893  if (size.height() > screen.height() || size.width() > screen.width()) {
1894  size = d->adjustMenuSizeForScreen(screen);
1895  adjustToDesktop = true;
1896  }
1897  // Layout is not right, we might be able to save horizontal space
1898  if (d->ncols >1 && size.height() < screen.height()) {
1899  size = d->adjustMenuSizeForScreen(screen);
1900  adjustToDesktop = true;
1901  }
1902  }
1903 
1904 #ifdef QT_KEYPAD_NAVIGATION
1905  if (!atAction && QApplication::keypadNavigationEnabled()) {
1906  // Try to have one item activated
1907  if (d->defaultAction && d->defaultAction->isEnabled()) {
1908  atAction = d->defaultAction;
1909  // TODO: This works for first level menus, not yet sub menus
1910  } else {
1911  foreach (QAction *action, d->actions)
1912  if (action->isEnabled()) {
1913  atAction = action;
1914  break;
1915  }
1916  }
1917  d->currentAction = atAction;
1918  }
1919 #endif
1920  if (d->ncols > 1) {
1921  pos.setY(screen.top() + desktopFrame);
1922  } else if (atAction) {
1923  for (int i = 0, above_height = 0; i < d->actions.count(); i++) {
1924  QAction *action = d->actions.at(i);
1925  if (action == atAction) {
1926  int newY = pos.y() - above_height;
1927  if (d->scroll && newY < desktopFrame) {
1928  d->scroll->scrollFlags = d->scroll->scrollFlags
1930  d->scroll->scrollOffset = newY;
1931  newY = desktopFrame;
1932  }
1933  pos.setY(newY);
1934 
1935  if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone
1937  int below_height = above_height + d->scroll->scrollOffset;
1938  for (int i2 = i; i2 < d->actionRects.count(); i2++)
1939  below_height += d->actionRects.at(i2).height();
1940  size.setHeight(below_height);
1941  }
1942  break;
1943  } else {
1944  above_height += d->actionRects.at(i).height();
1945  }
1946  }
1947  }
1948 
1949  QPoint mouse = QCursor::pos();
1950  d->mousePopupPos = mouse;
1951  const bool snapToMouse = !d->causedPopup.widget && (QRect(p.x() - 3, p.y() - 3, 6, 6).contains(mouse));
1952 
1953  const QSize menuSize(sizeHint());
1954  if (adjustToDesktop) {
1955  // handle popup falling "off screen"
1956  if (isRightToLeft()) {
1957  if (snapToMouse) // position flowing left from the mouse
1958  pos.setX(mouse.x() - size.width());
1959 
1960 #ifndef QT_NO_MENUBAR
1961  // if in a menubar, it should be right-aligned
1962  if (qobject_cast<QMenuBar*>(d->causedPopup.widget))
1963  pos.rx() -= size.width();
1964 #endif //QT_NO_MENUBAR
1965 
1966  if (pos.x() < screen.left() + desktopFrame)
1967  pos.setX(qMax(p.x(), screen.left() + desktopFrame));
1968  if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)
1969  pos.setX(qMax(p.x() - size.width(), screen.right() - desktopFrame - size.width() + 1));
1970  } else {
1971  if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)
1972  pos.setX(screen.right() - desktopFrame - size.width() + 1);
1973  if (pos.x() < screen.left() + desktopFrame)
1974  pos.setX(screen.left() + desktopFrame);
1975  }
1976  if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) {
1977  if(snapToMouse)
1978  pos.setY(qMin(mouse.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1));
1979  else
1980  pos.setY(qMax(p.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1));
1981  } else if (pos.y() < screen.top() + desktopFrame) {
1982  pos.setY(screen.top() + desktopFrame);
1983  }
1984 
1985  if (pos.y() < screen.top() + desktopFrame)
1986  pos.setY(screen.top() + desktopFrame);
1987  if (pos.y() + menuSize.height() - 1 > screen.bottom() - desktopFrame) {
1988  if (d->scroll) {
1989  d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown);
1990  int y = qMax(screen.y(),pos.y());
1991  size.setHeight(screen.bottom() - (desktopFrame * 2) - y);
1992  } else {
1993  // Too big for screen, bias to see bottom of menu (for some reason)
1994  pos.setY(screen.bottom() - size.height() + 1);
1995  }
1996  }
1997  }
1998  const int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this);
1999  QMenu *caused = qobject_cast<QMenu*>(d_func()->causedPopup.widget);
2000  if (caused && caused->geometry().width() + menuSize.width() + subMenuOffset < screen.width()) {
2001  QRect parentActionRect(caused->d_func()->actionRect(caused->d_func()->currentAction));
2002  const QPoint actionTopLeft = caused->mapToGlobal(parentActionRect.topLeft());
2003  parentActionRect.moveTopLeft(actionTopLeft);
2004  if (isRightToLeft()) {
2005  if ((pos.x() + menuSize.width() > parentActionRect.left() - subMenuOffset)
2006  && (pos.x() < parentActionRect.right()))
2007  {
2008  pos.rx() = parentActionRect.left() - menuSize.width();
2009  if (pos.x() < screen.x())
2010  pos.rx() = parentActionRect.right();
2011  if (pos.x() + menuSize.width() > screen.x() + screen.width())
2012  pos.rx() = screen.x();
2013  }
2014  } else {
2015  if ((pos.x() < parentActionRect.right() + subMenuOffset)
2016  && (pos.x() + menuSize.width() > parentActionRect.left()))
2017  {
2018  pos.rx() = parentActionRect.right();
2019  if (pos.x() + menuSize.width() > screen.x() + screen.width())
2020  pos.rx() = parentActionRect.left() - menuSize.width();
2021  if (pos.x() < screen.x())
2022  pos.rx() = screen.x() + screen.width() - menuSize.width();
2023  }
2024  }
2025  }
2026  setGeometry(QRect(pos, size));
2027 #ifndef QT_NO_EFFECTS
2029  int vGuess = QEffects::DownScroll;
2030  if (isRightToLeft()) {
2031  if ((snapToMouse && (pos.x() + size.width() / 2 > mouse.x())) ||
2032  (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 > d->causedPopup.widget->x()))
2033  hGuess = QEffects::RightScroll;
2034  } else {
2035  if ((snapToMouse && (pos.x() + size.width() / 2 < mouse.x())) ||
2036  (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 < d->causedPopup.widget->x()))
2037  hGuess = QEffects::LeftScroll;
2038  }
2039 
2040 #ifndef QT_NO_MENUBAR
2041  if ((snapToMouse && (pos.y() + size.height() / 2 < mouse.y())) ||
2042  (qobject_cast<QMenuBar*>(d->causedPopup.widget) &&
2043  pos.y() + size.width() / 2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y()))
2044  vGuess = QEffects::UpScroll;
2045 #endif
2047  bool doChildEffects = true;
2048 #ifndef QT_NO_MENUBAR
2049  if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget)) {
2050  doChildEffects = mb->d_func()->doChildEffects;
2051  mb->d_func()->doChildEffects = false;
2052  } else
2053 #endif
2054  if (QMenu *m = qobject_cast<QMenu*>(d->causedPopup.widget)) {
2055  doChildEffects = m->d_func()->doChildEffects;
2056  m->d_func()->doChildEffects = false;
2057  }
2058 
2059  if (doChildEffects) {
2061  qFadeEffect(this);
2062  else if (d->causedPopup.widget)
2063  qScrollEffect(this, qobject_cast<QMenu*>(d->causedPopup.widget) ? hGuess : vGuess);
2064  else
2065  qScrollEffect(this, hGuess | vGuess);
2066  } else {
2067  // kill any running effect
2068  qFadeEffect(0);
2069  qScrollEffect(0);
2070 
2071  show();
2072  }
2073  } else
2074 #endif
2075  {
2076  show();
2077  }
2078 
2079 #ifndef QT_NO_ACCESSIBILITY
2081 #endif
2082 }
2083 
2102 {
2103  return exec(pos());
2104 }
2105 
2106 
2142 QAction *QMenu::exec(const QPoint &p, QAction *action)
2143 {
2144  Q_D(QMenu);
2145  createWinId();
2146  QEventLoop eventLoop;
2147  d->eventLoop = &eventLoop;
2148  popup(p, action);
2149 
2150  QPointer<QObject> guard = this;
2151  (void) eventLoop.exec();
2152  if (guard.isNull())
2153  return 0;
2154 
2155  action = d->syncAction;
2156  d->syncAction = 0;
2157  d->eventLoop = 0;
2158  return action;
2159 }
2160 
2187 {
2188  QMenu menu(parent);
2189  menu.addActions(actions);
2190  return menu.exec(pos, at);
2191 }
2192 
2216 {
2217  // ### Qt 5: merge
2218  return exec(actions, pos, at, 0);
2219 }
2220 
2225 {
2226  Q_D(QMenu);
2227  emit aboutToHide();
2228  if (d->eventLoop)
2229  d->eventLoop->exit();
2230  d->setCurrentAction(0);
2231 #ifndef QT_NO_ACCESSIBILITY
2233 #endif
2234 #ifndef QT_NO_MENUBAR
2235  if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget))
2236  mb->d_func()->setCurrentAction(0);
2237 #endif
2238  d->mouseDown = 0;
2239  d->hasHadMouse = false;
2240  d->causedPopup.widget = 0;
2241  d->causedPopup.action = 0;
2242  if (d->scroll)
2243  d->scroll->scrollTimer.stop(); //make sure the timer stops
2244 }
2245 
2250 {
2251  Q_D(QMenu);
2252  d->updateActionRects();
2253  QPainter p(this);
2254  QRegion emptyArea = QRegion(rect());
2255 
2256  QStyleOptionMenuItem menuOpt;
2257  menuOpt.initFrom(this);
2258  menuOpt.state = QStyle::State_None;
2260  menuOpt.maxIconWidth = 0;
2261  menuOpt.tabWidth = 0;
2262  style()->drawPrimitive(QStyle::PE_PanelMenu, &menuOpt, &p, this);
2263 
2264  //draw the items that need updating..
2265  for (int i = 0; i < d->actions.count(); ++i) {
2266  QAction *action = d->actions.at(i);
2267  QRect adjustedActionRect = d->actionRects.at(i);
2268  if (!e->rect().intersects(adjustedActionRect)
2269  || d->widgetItems.value(action))
2270  continue;
2271  //set the clip region to be extra safe (and adjust for the scrollers)
2272  QRegion adjustedActionReg(adjustedActionRect);
2273  emptyArea -= adjustedActionReg;
2274  p.setClipRegion(adjustedActionReg);
2275 
2277  initStyleOption(&opt, action);
2278  opt.rect = adjustedActionRect;
2279  style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this);
2280  }
2281 
2282  const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
2283  //draw the scroller regions..
2284  if (d->scroll) {
2286  menuOpt.state |= QStyle::State_Enabled;
2287  if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) {
2288  menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight());
2289  emptyArea -= QRegion(menuOpt.rect);
2290  p.setClipRect(menuOpt.rect);
2291  style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);
2292  }
2293  if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) {
2294  menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2),
2295  d->scrollerHeight());
2296  emptyArea -= QRegion(menuOpt.rect);
2297  menuOpt.state |= QStyle::State_DownArrow;
2298  p.setClipRect(menuOpt.rect);
2299  style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);
2300  }
2301  }
2302  //paint the tear off..
2303  if (d->tearoff) {
2305  menuOpt.rect.setRect(fw, fw, width() - (fw * 2),
2306  style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this));
2307  if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
2308  menuOpt.rect.translate(0, d->scrollerHeight());
2309  emptyArea -= QRegion(menuOpt.rect);
2310  p.setClipRect(menuOpt.rect);
2311  menuOpt.state = QStyle::State_None;
2312  if (d->tearoffHighlighted)
2313  menuOpt.state |= QStyle::State_Selected;
2314  style()->drawControl(QStyle::CE_MenuTearoff, &menuOpt, &p, this);
2315  }
2316  //draw border
2317  if (fw) {
2318  QRegion borderReg;
2319  borderReg += QRect(0, 0, fw, height()); //left
2320  borderReg += QRect(width()-fw, 0, fw, height()); //right
2321  borderReg += QRect(0, 0, width(), fw); //top
2322  borderReg += QRect(0, height()-fw, width(), fw); //bottom
2323  p.setClipRegion(borderReg);
2324  emptyArea -= borderReg;
2325  QStyleOptionFrame frame;
2326  frame.rect = rect();
2327  frame.palette = palette();
2328  frame.state = QStyle::State_None;
2330  frame.midLineWidth = 0;
2331  style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, &p, this);
2332  }
2333 
2334  //finally the rest of the space
2335  p.setClipRegion(emptyArea);
2336  menuOpt.state = QStyle::State_None;
2339  menuOpt.rect = rect();
2340  menuOpt.menuRect = rect();
2341  style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);
2342 }
2343 
2344 #ifndef QT_NO_WHEELEVENT
2345 
2349 {
2350  Q_D(QMenu);
2351  if (d->scroll && rect().contains(e->pos()))
2352  d->scrollMenu(e->delta() > 0 ?
2354 }
2355 #endif
2356 
2361 {
2362  Q_D(QMenu);
2363  if (d->aboutToHide || d->mouseEventTaken(e))
2364  return;
2365  if (!rect().contains(e->pos())) {
2366  if (d->noReplayFor
2367  && QRect(d->noReplayFor->mapToGlobal(QPoint()), d->noReplayFor->size()).contains(e->globalPos()))
2369  if (d->eventLoop) // synchronous operation
2370  d->syncAction = 0;
2371  d->hideUpToMenuBar();
2372  return;
2373  }
2374  d->mouseDown = this;
2375 
2376  QAction *action = d->actionAt(e->pos());
2377  d->setCurrentAction(action, 20);
2378  update();
2379 }
2380 
2385 {
2386  Q_D(QMenu);
2387  if (d->aboutToHide || d->mouseEventTaken(e))
2388  return;
2389  if(d->mouseDown != this) {
2390  d->mouseDown = 0;
2391  return;
2392  }
2393 
2394  d->mouseDown = 0;
2395  d->setSyncAction();
2396  QAction *action = d->actionAt(e->pos());
2397 
2398  if (action && action == d->currentAction) {
2399  if (!action->menu()){
2400 #if defined(Q_WS_WIN)
2401  //On Windows only context menus can be activated with the right button
2402  if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0)
2403 #endif
2404  d->activateAction(action, QAction::Trigger);
2405  }
2406  } else if (d->hasMouseMoved(e->globalPos())) {
2407  d->hideUpToMenuBar();
2408  }
2409 }
2410 
2415 {
2416  Q_D(QMenu);
2417  if (e->type() == QEvent::StyleChange || e->type() == QEvent::FontChange ||
2419  d->itemsDirty = 1;
2421  if (isVisible())
2422  resize(sizeHint());
2423  if (!style()->styleHint(QStyle::SH_Menu_Scrollable, 0, this)) {
2424  delete d->scroll;
2425  d->scroll = 0;
2426  } else if (!d->scroll) {
2427  d->scroll = new QMenuPrivate::QMenuScroller;
2428  d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
2429  }
2430  } else if (e->type() == QEvent::EnabledChange) {
2431  if (d->tornPopup) // torn-off menu
2432  d->tornPopup->setEnabled(isEnabled());
2433  d->menuAction->setEnabled(isEnabled());
2434 #if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
2435  if (d->mac_menu)
2436  d->setMacMenuEnabled(isEnabled());
2437 #endif
2438  }
2440 }
2441 
2442 
2446 bool
2448 {
2449  Q_D(QMenu);
2450  switch (e->type()) {
2451  case QEvent::Polish:
2452  d->updateLayoutDirection();
2453  break;
2454  case QEvent::ShortcutOverride: {
2455  QKeyEvent *kev = static_cast<QKeyEvent*>(e);
2456  if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down
2457  || kev->key() == Qt::Key_Left || kev->key() == Qt::Key_Right
2458  || kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return
2459  || kev->key() == Qt::Key_Escape) {
2460  e->accept();
2461  return true;
2462  }
2463  }
2464  break;
2465  case QEvent::KeyPress: {
2466  QKeyEvent *ke = (QKeyEvent*)e;
2467  if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
2468  keyPressEvent(ke);
2469  return true;
2470  }
2471  } break;
2472  case QEvent::ContextMenu:
2473  if(d->menuDelayTimer.isActive()) {
2474  d->menuDelayTimer.stop();
2476  }
2477  break;
2478  case QEvent::Resize: {
2479  QStyleHintReturnMask menuMask;
2480  QStyleOption option;
2481  option.initFrom(this);
2482  if (style()->styleHint(QStyle::SH_Menu_Mask, &option, this, &menuMask)) {
2483  setMask(menuMask.region);
2484  }
2485  d->itemsDirty = 1;
2486  d->updateActionRects();
2487  break; }
2488  case QEvent::Show:
2489  d->mouseDown = 0;
2490  d->updateActionRects();
2491  if (d->currentAction)
2492  d->popupAction(d->currentAction, 0, false);
2493  break;
2494 #ifndef QT_NO_WHATSTHIS
2496  e->setAccepted(d->whatsThis.size());
2497  if (QAction *action = d->actionAt(static_cast<QHelpEvent*>(e)->pos())) {
2498  if (action->whatsThis().size() || action->menu())
2499  e->accept();
2500  }
2501  return true;
2502 #endif
2503 #ifdef QT_SOFTKEYS_ENABLED
2504  case QEvent::LanguageChange: {
2507  }
2508  break;
2509 #endif
2510  default:
2511  break;
2512  }
2513  return QWidget::event(e);
2514 }
2515 
2520 {
2521  setFocus();
2523  keyPressEvent(&ev);
2524  return true;
2525 }
2526 
2531 {
2532  Q_D(QMenu);
2533  d->updateActionRects();
2534  int key = e->key();
2535  if (isRightToLeft()) { // in reverse mode open/close key for submenues are reversed
2536  if (key == Qt::Key_Left)
2537  key = Qt::Key_Right;
2538  else if (key == Qt::Key_Right)
2539  key = Qt::Key_Left;
2540  }
2541 #ifndef Q_WS_MAC
2542  if (key == Qt::Key_Tab) //means down
2543  key = Qt::Key_Down;
2544  if (key == Qt::Key_Backtab) //means up
2545  key = Qt::Key_Up;
2546 #endif
2547 
2548  bool key_consumed = false;
2549  switch(key) {
2550  case Qt::Key_Home:
2551  key_consumed = true;
2552  if (d->scroll)
2553  d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollTop, true);
2554  break;
2555  case Qt::Key_End:
2556  key_consumed = true;
2557  if (d->scroll)
2558  d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollBottom, true);
2559  break;
2560  case Qt::Key_PageUp:
2561  key_consumed = true;
2562  if (d->currentAction && d->scroll) {
2563  if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
2564  d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollUp, true, true);
2565  else
2566  d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollTop, true);
2567  }
2568  break;
2569  case Qt::Key_PageDown:
2570  key_consumed = true;
2571  if (d->currentAction && d->scroll) {
2572  if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)
2573  d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollDown, true, true);
2574  else
2575  d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollBottom, true);
2576  }
2577  break;
2578  case Qt::Key_Up:
2579  case Qt::Key_Down: {
2580  key_consumed = true;
2581  QAction *nextAction = 0;
2583  if (!d->currentAction) {
2584  if(key == Qt::Key_Down) {
2585  for(int i = 0; i < d->actions.count(); ++i) {
2586  QAction *act = d->actions.at(i);
2587  if (d->actionRects.at(i).isNull())
2588  continue;
2589  if (!act->isSeparator() &&
2591  || act->isEnabled())) {
2592  nextAction = act;
2593  break;
2594  }
2595  }
2596  } else {
2597  for(int i = d->actions.count()-1; i >= 0; --i) {
2598  QAction *act = d->actions.at(i);
2599  if (d->actionRects.at(i).isNull())
2600  continue;
2601  if (!act->isSeparator() &&
2603  || act->isEnabled())) {
2604  nextAction = act;
2605  break;
2606  }
2607  }
2608  }
2609  } else {
2610  for(int i = 0, y = 0; !nextAction && i < d->actions.count(); i++) {
2611  QAction *act = d->actions.at(i);
2612  if (act == d->currentAction) {
2613  if (key == Qt::Key_Up) {
2614  for(int next_i = i-1; true; next_i--) {
2615  if (next_i == -1) {
2617  break;
2618  if (d->scroll)
2620  next_i = d->actionRects.count()-1;
2621  }
2622  QAction *next = d->actions.at(next_i);
2623  if (next == d->currentAction)
2624  break;
2625  if (d->actionRects.at(next_i).isNull())
2626  continue;
2627  if (next->isSeparator() ||
2628  (!next->isEnabled() &&
2630  continue;
2631  nextAction = next;
2632  if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) {
2633  int topVisible = d->scrollerHeight();
2634  if (d->tearoff)
2635  topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
2636  if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height())
2638  }
2639  break;
2640  }
2641  if (!nextAction && d->tearoff)
2642  d->tearoffHighlighted = 1;
2643  } else {
2644  y += d->actionRects.at(i).height();
2645  for(int next_i = i+1; true; next_i++) {
2646  if (next_i == d->actionRects.count()) {
2648  break;
2649  if (d->scroll)
2651  next_i = 0;
2652  }
2653  QAction *next = d->actions.at(next_i);
2654  if (next == d->currentAction)
2655  break;
2656  if (d->actionRects.at(next_i).isNull())
2657  continue;
2658  if (next->isSeparator() ||
2659  (!next->isEnabled() &&
2661  continue;
2662  nextAction = next;
2663  if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) {
2664  int bottomVisible = height() - d->scrollerHeight();
2665  if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
2666  bottomVisible -= d->scrollerHeight();
2667  if (d->tearoff)
2668  bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
2669  if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible)
2671  }
2672  break;
2673  }
2674  }
2675  break;
2676  }
2677  y += d->actionRects.at(i).height();
2678  }
2679  }
2680  if (nextAction) {
2681  if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) {
2682  d->scroll->scrollTimer.stop();
2683  d->scrollMenu(nextAction, scroll_loc);
2684  }
2685  d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
2686  }
2687  break; }
2688 
2689  case Qt::Key_Right:
2690  if (d->currentAction && d->currentAction->isEnabled() && d->currentAction->menu()) {
2691  d->popupAction(d->currentAction, 0, true);
2692  key_consumed = true;
2693  break;
2694  }
2695  //FALL THROUGH
2696  case Qt::Key_Left: {
2697  if (d->currentAction && !d->scroll) {
2698  QAction *nextAction = 0;
2699  if (key == Qt::Key_Left) {
2700  QRect actionR = d->actionRect(d->currentAction);
2701  for(int x = actionR.left()-1; !nextAction && x >= 0; x--)
2702  nextAction = d->actionAt(QPoint(x, actionR.center().y()));
2703  } else {
2704  QRect actionR = d->actionRect(d->currentAction);
2705  for(int x = actionR.right()+1; !nextAction && x < width(); x++)
2706  nextAction = d->actionAt(QPoint(x, actionR.center().y()));
2707  }
2708  if (nextAction) {
2709  d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
2710  key_consumed = true;
2711  }
2712  }
2713  if (!key_consumed && key == Qt::Key_Left && qobject_cast<QMenu*>(d->causedPopup.widget)) {
2714  QPointer<QWidget> caused = d->causedPopup.widget;
2715  d->hideMenu(this);
2716  if (caused)
2717  caused->setFocus();
2718  key_consumed = true;
2719  }
2720  break; }
2721 
2722  case Qt::Key_Alt:
2723  if (d->tornoff)
2724  break;
2725 
2726  key_consumed = true;
2728  {
2729  d->hideMenu(this);
2730 #ifndef QT_NO_MENUBAR
2731  if (QMenuBar *mb = qobject_cast<QMenuBar*>(QApplication::focusWidget())) {
2732  mb->d_func()->setKeyboardMode(false);
2733  }
2734 #endif
2735  }
2736  break;
2737 
2738  case Qt::Key_Escape:
2739 #ifdef QT_KEYPAD_NAVIGATION
2740  case Qt::Key_Back:
2741 #endif
2742  key_consumed = true;
2743  if (d->tornoff) {
2744  close();
2745  return;
2746  }
2747  {
2748  QPointer<QWidget> caused = d->causedPopup.widget;
2749  d->hideMenu(this); // hide after getting causedPopup
2750 #ifndef QT_NO_MENUBAR
2751  if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
2752  mb->d_func()->setCurrentAction(d->menuAction);
2753  mb->d_func()->setKeyboardMode(true);
2754  }
2755 #endif
2756  }
2757  break;
2758 
2759  case Qt::Key_Space:
2761  break;
2762  // for motif, fall through
2763 #ifdef QT_KEYPAD_NAVIGATION
2764  case Qt::Key_Select:
2765 #endif
2766  case Qt::Key_Return:
2767  case Qt::Key_Enter: {
2768  if (!d->currentAction) {
2769  d->setFirstActionActive();
2770  key_consumed = true;
2771  break;
2772  }
2773 
2774  d->setSyncAction();
2775 
2776  if (d->currentAction->menu())
2777  d->popupAction(d->currentAction, 0, true);
2778  else
2779  d->activateAction(d->currentAction, QAction::Trigger);
2780  key_consumed = true;
2781  break; }
2782 
2783 #ifndef QT_NO_WHATSTHIS
2784  case Qt::Key_F1:
2785  if (!d->currentAction || d->currentAction->whatsThis().isNull())
2786  break;
2788  d->activateAction(d->currentAction, QAction::Trigger);
2789  return;
2790 #endif
2791  default:
2792  key_consumed = false;
2793  }
2794 
2795  if (!key_consumed) { // send to menu bar
2796  if ((!e->modifiers() || e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ShiftModifier) &&
2797  e->text().length()==1) {
2798  bool activateAction = false;
2799  QAction *nextAction = 0;
2800  if (style()->styleHint(QStyle::SH_Menu_KeyboardSearch, 0, this) && !e->modifiers()) {
2801  int best_match_count = 0;
2802  d->searchBufferTimer.start(2000, this);
2803  d->searchBuffer += e->text();
2804  for(int i = 0; i < d->actions.size(); ++i) {
2805  int match_count = 0;
2806  if (d->actionRects.at(i).isNull())
2807  continue;
2808  QAction *act = d->actions.at(i);
2809  const QString act_text = act->text();
2810  for(int c = 0; c < d->searchBuffer.size(); ++c) {
2811  if(act_text.indexOf(d->searchBuffer.at(c), 0, Qt::CaseInsensitive) != -1)
2812  ++match_count;
2813  }
2814  if(match_count > best_match_count) {
2815  best_match_count = match_count;
2816  nextAction = act;
2817  }
2818  }
2819  }
2820 #ifndef QT_NO_SHORTCUT
2821  else {
2822  int clashCount = 0;
2823  QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;
2824  QChar c = e->text().at(0).toUpper();
2825  for(int i = 0; i < d->actions.size(); ++i) {
2826  if (d->actionRects.at(i).isNull())
2827  continue;
2828  QAction *act = d->actions.at(i);
2829  QKeySequence sequence = QKeySequence::mnemonic(act->text());
2830  int key = sequence[0] & 0xffff;
2831  if (key == c.unicode()) {
2832  clashCount++;
2833  if (!first)
2834  first = act;
2835  if (act == d->currentAction)
2836  currentSelected = act;
2837  else if (!firstAfterCurrent && currentSelected)
2838  firstAfterCurrent = act;
2839  }
2840  }
2841  if (clashCount == 1)
2842  activateAction = true;
2843  if (clashCount >= 1) {
2844  if (clashCount == 1 || !currentSelected || !firstAfterCurrent)
2845  nextAction = first;
2846  else
2847  nextAction = firstAfterCurrent;
2848  }
2849  }
2850 #endif
2851  if (nextAction) {
2852  key_consumed = true;
2853  if(d->scroll)
2854  d->scrollMenu(nextAction, QMenuPrivate::QMenuScroller::ScrollCenter, false);
2855  d->setCurrentAction(nextAction, 0, QMenuPrivate::SelectedFromElsewhere, true);
2856  if (!nextAction->menu() && activateAction) {
2857  d->setSyncAction();
2858  d->activateAction(nextAction, QAction::Trigger);
2859  }
2860  }
2861  }
2862  if (!key_consumed) {
2863 #ifndef QT_NO_MENUBAR
2864  if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->topCausedWidget())) {
2865  QAction *oldAct = mb->d_func()->currentAction;
2866  QApplication::sendEvent(mb, e);
2867  if (mb->d_func()->currentAction != oldAct)
2868  key_consumed = true;
2869  }
2870 #endif
2871  }
2872 
2873 #ifdef Q_OS_WIN32
2874  if (key_consumed && (e->key() == Qt::Key_Control || e->key() == Qt::Key_Shift || e->key() == Qt::Key_Meta))
2876 #endif // Q_OS_WIN32
2877  }
2878  if (key_consumed)
2879  e->accept();
2880  else
2881  e->ignore();
2882 }
2883 
2888 {
2889  Q_D(QMenu);
2890  if (!isVisible() || d->aboutToHide || d->mouseEventTaken(e))
2891  return;
2892  d->motions++;
2893  if (d->motions == 0) // ignore first mouse move event (see enterEvent())
2894  return;
2895  d->hasHadMouse = d->hasHadMouse || rect().contains(e->pos());
2896 
2897  QAction *action = d->actionAt(e->pos());
2898  if (!action || action->isSeparator()) {
2899  if (d->hasHadMouse
2900  && d->sloppyDelayTimer == 0 // Keep things as they are while we're moving to the submenu
2901  && (!d->currentAction || (action && action->isSeparator())
2902  || !(d->currentAction->menu() && d->currentAction->menu()->isVisible())))
2903  d->setCurrentAction(0);
2904  return;
2905  } else if(e->buttons()) {
2906  d->mouseDown = this;
2907  }
2908  if (d->sloppyRegion.contains(e->pos())) {
2909  if (d->sloppyAction != action && d->sloppyDelayTimer != 0) {
2910  killTimer(d->sloppyDelayTimer);
2911  d->sloppyDelayTimer = 0;
2912  }
2913  if (d->sloppyDelayTimer == 0) {
2914  d->sloppyAction = action;
2915  d->sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6);
2916  }
2917  } else if (action != d->currentAction) {
2918  d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this));
2919  }
2920 }
2921 
2926 {
2927  d_func()->motions = -1; // force us to ignore the generate mouse move in mouseMoveEvent()
2928 }
2929 
2934 {
2935  Q_D(QMenu);
2936  d->sloppyAction = 0;
2937  if (!d->sloppyRegion.isEmpty())
2938  d->sloppyRegion = QRegion();
2939  if (!d->activeMenu && d->currentAction)
2940  setActiveAction(0);
2941 }
2942 
2946 void
2948 {
2949  Q_D(QMenu);
2950  if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) {
2951  d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection);
2952  if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone)
2953  d->scroll->scrollTimer.stop();
2954  } else if(d->menuDelayTimer.timerId() == e->timerId()) {
2955  d->menuDelayTimer.stop();
2957  } else if (d->sloppyDelayTimer == e->timerId()) {
2958  killTimer(d->sloppyDelayTimer);
2959  d->sloppyDelayTimer = 0;
2961  } else if(d->searchBufferTimer.timerId() == e->timerId()) {
2962  d->searchBuffer.clear();
2963  }
2964 }
2965 
2970 {
2971  Q_D(QMenu);
2972  d->itemsDirty = 1;
2973  setAttribute(Qt::WA_Resized, false);
2974  if (d->tornPopup)
2975  d->tornPopup->syncWithMenu(this, e);
2976  if (e->type() == QEvent::ActionAdded) {
2977  if(!d->tornoff) {
2978  connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
2979  connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
2980  }
2981  if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
2982  QWidget *widget = wa->requestWidget(this);
2983  if (widget)
2984  d->widgetItems.insert(wa, widget);
2985  }
2986  } else if (e->type() == QEvent::ActionRemoved) {
2987  e->action()->disconnect(this);
2988  if (e->action() == d->currentAction)
2989  d->currentAction = 0;
2990  if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
2991  if (QWidget *widget = d->widgetItems.value(wa))
2992  wa->releaseWidget(widget);
2993  }
2994  d->widgetItems.remove(e->action());
2995  }
2996 
2997 #ifdef Q_WS_MAC
2998  if (d->mac_menu) {
2999  if (e->type() == QEvent::ActionAdded)
3000  d->mac_menu->addAction(e->action(), d->mac_menu->findAction(e->before()), d);
3001  else if (e->type() == QEvent::ActionRemoved)
3002  d->mac_menu->removeAction(e->action());
3003  else if (e->type() == QEvent::ActionChanged)
3004  d->mac_menu->syncAction(e->action());
3005  }
3006 #endif
3007 
3008 #if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
3009  if (!d->wce_menu)
3010  d->wce_menu = new QMenuPrivate::QWceMenuPrivate;
3011  if (e->type() == QEvent::ActionAdded)
3012  d->wce_menu->addAction(e->action(), d->wce_menu->findAction(e->before()));
3013  else if (e->type() == QEvent::ActionRemoved)
3014  d->wce_menu->removeAction(e->action());
3015  else if (e->type() == QEvent::ActionChanged)
3016  d->wce_menu->syncAction(e->action());
3017 #endif
3018 
3019 #ifdef Q_WS_S60
3020  if (!d->symbian_menu)
3021  d->symbian_menu = new QMenuPrivate::QSymbianMenuPrivate;
3022  if (e->type() == QEvent::ActionAdded)
3023  d->symbian_menu->addAction(e->action(), d->symbian_menu->findAction(e->before()));
3024  else if (e->type() == QEvent::ActionRemoved)
3025  d->symbian_menu->removeAction(e->action());
3026  else if (e->type() == QEvent::ActionChanged)
3027  d->symbian_menu->syncAction(e->action());
3028 #endif
3029  if (isVisible()) {
3030  d->updateActionRects();
3031  resize(sizeHint());
3032  update();
3033  }
3034 }
3035 
3040 {
3041  if (d_func()->sloppyAction)
3042  d_func()->setCurrentAction(d_func()->sloppyAction, 0);
3043 }
3044 
3049 {
3050  Q_D(QMenu);
3051 
3052  //hide the current item
3053  if (QMenu *menu = d->activeMenu) {
3054  d->activeMenu = 0;
3055  d->hideMenu(menu);
3056  }
3057 
3058  if (!d->currentAction || !d->currentAction->isEnabled() || !d->currentAction->menu() ||
3059  !d->currentAction->menu()->isEnabled() || d->currentAction->menu()->isVisible())
3060  return;
3061 
3062  //setup
3063  d->activeMenu = d->currentAction->menu();
3064  d->activeMenu->d_func()->causedPopup.widget = this;
3065  d->activeMenu->d_func()->causedPopup.action = d->currentAction;
3066 
3067  int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this);
3068  const QRect actionRect(d->actionRect(d->currentAction));
3069  const QSize menuSize(d->activeMenu->sizeHint());
3070  const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top())));
3071 
3072  QPoint pos(rightPos);
3073 
3074  //calc sloppy focus buffer
3075  if (style()->styleHint(QStyle::SH_Menu_SloppySubMenus, 0, this)) {
3076  QPoint cur = QCursor::pos();
3077  if (actionRect.contains(mapFromGlobal(cur))) {
3078  QPoint pts[4];
3079  pts[0] = QPoint(cur.x(), cur.y() - 2);
3080  pts[3] = QPoint(cur.x(), cur.y() + 2);
3081  if (pos.x() >= cur.x()) {
3082  pts[1] = QPoint(geometry().right(), pos.y());
3083  pts[2] = QPoint(geometry().right(), pos.y() + menuSize.height());
3084  } else {
3085  pts[1] = QPoint(pos.x() + menuSize.width(), pos.y());
3086  pts[2] = QPoint(pos.x() + menuSize.width(), pos.y() + menuSize.height());
3087  }
3088  QPolygon points(4);
3089  for(int i = 0; i < 4; i++)
3090  points.setPoint(i, mapFromGlobal(pts[i]));
3091  d->sloppyRegion = QRegion(points);
3092  }
3093  }
3094 
3095  //do the popup
3096  d->activeMenu->popup(pos);
3097 }
3098 
3164 void QMenu::setNoReplayFor(QWidget *noReplayFor)
3165 {
3166 #ifdef Q_WS_WIN
3167  d_func()->noReplayFor = noReplayFor;
3168 #else
3169  Q_UNUSED(noReplayFor);
3170 #endif
3171 }
3172 
3188 bool QMenu::separatorsCollapsible() const
3189 {
3190  Q_D(const QMenu);
3191  return d->collapsibleSeparators;
3192 }
3193 
3195 {
3196  Q_D(QMenu);
3197  if (d->collapsibleSeparators == collapse)
3198  return;
3199 
3200  d->collapsibleSeparators = collapse;
3201  d->itemsDirty = 1;
3202  if (isVisible()) {
3203  d->updateActionRects();
3204  update();
3205  }
3206 #ifdef Q_WS_MAC
3207  if (d->mac_menu)
3208  d->syncSeparatorsCollapsible(collapse);
3209 #endif
3210 }
3211 
3212 #ifdef QT3_SUPPORT
3213 
3214 int QMenu::insertAny(const QIcon *icon, const QString *text, const QObject *receiver, const char *member,
3215  const QKeySequence *shortcut, const QMenu *popup, int id, int index)
3216 {
3217  QAction *act = popup ? popup->menuAction() : new QAction(this);
3218  if (id != -1)
3219  static_cast<QMenuItem*>(act)->setId(id);
3220  if (icon)
3221  act->setIcon(*icon);
3222  if (text)
3223  act->setText(*text);
3224  if (shortcut)
3225  act->setShortcut(*shortcut);
3226  if (receiver && member)
3227  QObject::connect(act, SIGNAL(activated(int)), receiver, member);
3228  if (index == -1 || index >= actions().count())
3229  addAction(act);
3230  else
3231  insertAction(actions().value(index), act);
3232  return findIdForAction(act);
3233 }
3234 
3238 int QMenu::insertItem(QMenuItem *item, int id, int index)
3239 {
3240  if (index == -1 || index >= actions().count())
3241  addAction(item);
3242  else
3243  insertAction(actions().value(index), item);
3244  if (id > -1)
3245  item->d_func()->id = id;
3246  return findIdForAction(item);
3247 }
3248 
3254 {
3255  QAction *act = new QAction(this);
3256  act->setSeparator(true);
3257  if (index == -1 || index >= actions().count())
3258  addAction(act);
3259  else
3260  insertAction(actions().value(index), act);
3261  return findIdForAction(act);
3262 }
3263 
3264 QAction *QMenu::findActionForId(int id) const
3265 {
3266  Q_D(const QMenu);
3267  for (int i = 0; i < d->actions.size(); ++i) {
3268  QAction *act = d->actions.at(i);
3269  if (findIdForAction(act)== id)
3270  return act;
3271  }
3272  return 0;
3273 }
3274 
3278 QMenuItem *QMenu::findPopup( QMenu *popup, int *index )
3279 {
3280  QList<QAction *> list = actions();
3281  for (int i = 0; i < list.size(); ++i) {
3282  QAction *act = list.at(i);
3283  if (act->menu() == popup) {
3284  QMenuItem *item = static_cast<QMenuItem *>(act);
3285  if (index)
3286  *index = act->d_func()->id;
3287  return item;
3288  }
3289  }
3290  return 0;
3291 }
3292 
3293 
3297 bool QMenu::setItemParameter(int id, int param)
3298 {
3299  if (QAction *act = findActionForId(id)) {
3300  act->d_func()->param = param;
3301  return true;
3302  }
3303  return false;
3304 }
3305 
3309 int QMenu::itemParameter(int id) const
3310 {
3311  if (QAction *act = findActionForId(id))
3312  return act->d_func()->param;
3313  return id;
3314 }
3315 
3319 void QMenu::setId(int index, int id)
3320 {
3321  if(QAction *act = actions().value(index))
3322  act->d_func()->id = id;
3323 }
3324 
3328 int QMenu::frameWidth() const
3329 {
3330  return style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
3331 }
3332 
3333 int QMenu::findIdForAction(QAction *act) const
3334 {
3335  if (!act)
3336  return -1;
3337  return act->d_func()->id;
3338 }
3339 #endif // QT3_SUPPORT
3340 
3753 
3754 // for private slots
3755 #include "moc_qmenu.cpp"
3756 #include "qmenu.moc"
3757 
3758 #endif // QT_NO_MENU
uint tearoff
Definition: qmenu_p.h:272
void setSeparatorsCollapsible(bool collapse)
Definition: qmenu.cpp:3194
bool isSeparator() const
Returns true if this action is a separator action; otherwise it returns false.
Definition: qaction.cpp:839
QPoint pos() const
int startTimer(int interval)
Starts a timer and returns a timer identifier, or returns zero if it could not start a timer...
Definition: qobject.cpp:1623
QPointer< QMenu > causedMenu
Definition: qmenu.cpp:110
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
void setActiveAction(QAction *act)
Sets the currently highlighted action to act.
Definition: qmenu.cpp:1707
QRect menuRect
the rectangle for the entire menu
Definition: qstyleoption.h:449
QAction * before() const
If type() is ActionAdded , returns the action that should appear before action(). ...
Definition: qevent.h:640
double d
Definition: qnumeric_p.h:62
static Qt::LayoutDirection layoutDirection()
void internalSetSloppyAction()
Definition: qmenu.cpp:3039
static void updateAccessibility(QObject *, int who, Event reason)
Notifies accessibility clients about a change in object&#39;s accessibility information.
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
bool focusNextPrevChild(bool next)
Reimplemented Function
Definition: qmenu.cpp:2519
bool isEnabled() const
Definition: qaction.cpp:1208
bool blockSignals(bool b)
If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke...
Definition: qobject.cpp:1406
The QKeyEvent class describes a key event.
Definition: qevent.h:224
int indexOf(QAction *act) const
Definition: qmenu_p.h:269
static QPushButtonPrivate * get(QPushButton *b)
Definition: qpushbutton_p.h:71
bool isNull() const
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition: qrect.h:231
QRect actionGeometry(QAction *) const
Returns the geometry of action act.
Definition: qmenu.cpp:1797
void setShortcut(const QKeySequence &shortcut)
Definition: qaction.cpp:450
friend class QAction
Definition: qmenu.h:415
static QMenu * mouseDown
Definition: qmenu_p.h:208
void setHeight(int h)
Sets the height of the rectangle to the given height.
Definition: qrect.h:445
static QString standardSoftKeyText(StandardSoftKey standardKey)
static void beep()
Sounds the bell, using the default volume and sound.
double qreal
Definition: qglobal.h:1193
int y() const
void setBottom(int pos)
Sets the bottom edge of the rectangle to the given y coordinate.
Definition: qrect.h:267
short rightmargin
Definition: qwidget_p.h:746
unsigned char c[8]
Definition: qnumeric_p.h:62
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
The QFontMetrics class provides font metrics information.
Definition: qfontmetrics.h:65
QList< QPointer< QWidget > > calcCausedStack() const
Definition: qmenu.cpp:109
uint collapsibleSeparators
Definition: qmenu_p.h:201
void setNoReplayFor(QWidget *widget)
Definition: qmenu.cpp:3164
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false)
Definition: qmenu.cpp:873
void setParent(QWidget *parent)
Sets the parent of the widget to parent, and resets the window flags.
Definition: qwidget.cpp:10479
struct QMenuPrivate::QMenuScroller * scroll
int motions
Definition: qmenu_p.h:212
QSize size() const
QPointer< QWidget > widget
QPointer< QMenu > activeMenu
Definition: qmenu_p.h:254
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
void _q_overrideMenuActionDestroyed()
Definition: qmenu.cpp:685
QAction * insertSeparator(QAction *before)
This convenience function creates a new separator action, i.e.
Definition: qmenu.cpp:1612
QKeySequence shortcut
the action&#39;s primary shortcut key
Definition: qaction.h:83
bool showStatusText(QWidget *widget=0)
Updates the relevant status bar for the widget specified by sending a QStatusTipEvent to its parent w...
Definition: qaction.cpp:1315
void activate(ActionEvent event)
Sends the relevant signals for ActionEvent event.
Definition: qaction.cpp:1326
short topmargin
Definition: qwidget_p.h:745
void setSeparator(bool b)
If b is true then this action will be considered a separator.
Definition: qaction.cpp:823
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
QVector< T > & fill(const T &t, int size=-1)
Assigns value to all items in the vector.
Definition: qvector.h:665
void ensurePolished() const
Ensures that the widget has been polished by QStyle (i.e., has a proper font and palette).
Definition: qwidget.cpp:10024
QStyle::State state
the style flags that are used when drawing the control
Definition: qstyleoption.h:88
#define it(className, varName)
The QStyleOptionMenuItem class is used to describe the parameter necessary for drawing a menu item...
Definition: qstyleoption.h:435
bool isNull() const
Returns true if the referenced object has been destroyed or if there is no referenced object; otherwi...
Definition: qpointer.h:70
void keyPressEvent(QKeyEvent *)
Reimplemented Function
Definition: qmenu.cpp:2530
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
QIcon icon
the icon for the menu item
Definition: qstyleoption.h:451
The QWheelEvent class contains parameters that describe a wheel event.
Definition: qevent.h:139
void popup(const QPoint &pos, QAction *at=0)
Displays the menu so that the action atAction will be at the specified global position p...
Definition: qmenu.cpp:1847
QBasicTimer menuDelayTimer
Definition: qmenu_p.h:218
void updateActionRects() const
Definition: qmenu.cpp:239
void hovered(QAction *action)
This signal is emitted when a menu action is highlighted; action is the action that caused the signal...
bool isVisible() const
Definition: qwidget.h:1005
ActionEvent
This enum type is used when calling QAction::activate()
Definition: qaction.h:176
static QSize globalStrut()
QRegion sloppyRegion
Definition: qmenu_p.h:280
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const =0
Returns the value of the given pixel metric.
QFont font
the font used for the menu item text
Definition: qstyleoption.h:454
#define at(className, varName)
static QKeySequence mnemonic(const QString &text)
Returns the shortcut key sequence for the mnemonic in text, or an empty key sequence if no mnemonics ...
void setClipRect(const QRectF &, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip region to the given rectangle using the given clip operation...
Definition: qpainter.cpp:2801
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
friend class QFontMetrics
Definition: qwidget.h:749
void setAccepted(bool accepted)
Definition: qcoreevent.h:306
QString text
the action&#39;s descriptive text
Definition: qaction.h:76
#define SLOT(a)
Definition: qobjectdefs.h:226
void changeEvent(QEvent *)
Reimplemented Function
Definition: qmenu.cpp:2414
QIcon icon() const
Qt::FocusPolicy focusPolicy
the way the widget accepts keyboard focus
Definition: qwidget.h:187
bool activationRecursionGuard
Definition: qmenu_p.h:205
void actionEvent(QActionEvent *e)
This event handler is called with the given event whenever the widget&#39;s actions are changed...
Definition: qmenu.cpp:142
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QSize sizeHint() const
Reimplemented Function
Definition: qmenu.cpp:1805
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt=0, const QWidget *widget=0, QStyleHintReturn *returnData=0) const =0
Returns an integer representing the specified style hint for the given widget described by the provid...
QSize expandedTo(const QSize &) const
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition: qsize.h:187
QAction * activeAction() const
Returns the currently highlighted action, or 0 if no action is currently highlighted.
Definition: qmenu.cpp:1720
void setLayoutDirection_helper(Qt::LayoutDirection)
Definition: qwidget.cpp:5153
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
bool isActive() const
Returns true if the timer is running and has not been stopped; otherwise returns false.
Definition: qbasictimer.h:62
QAction * defaultMenuAction
Definition: qmenu_p.h:286
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
int maxIconWidth
the maximum icon width for the icon in the menu item
Definition: qstyleoption.h:452
void setSyncAction()
Definition: qmenu.cpp:534
The QPushButton widget provides a command button.
Definition: qpushbutton.h:57
void init(const QWidget *w)
Use initFrom(widget) instead.
long ASN1_INTEGER_get ASN1_INTEGER * a
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
void init()
Definition: qmenu.cpp:155
static bool bypassGraphicsProxyWidget(const QWidget *p)
Returns true if p or any of its parents enable the Qt::BypassGraphicsProxyWidget window flag...
Definition: qwidget_p.h:353
void setCurrentAction(QAction *, int popup=-1, SelectionReason reason=SelectedFromElsewhere, bool activateFirst=false)
Definition: qmenu.cpp:576
The QActionEvent class provides an event that is generated when a QAction is added, removed, or changed.
Definition: qevent.h:632
The QPolygon class provides a vector of points using integer precision.
Definition: qpolygon.h:60
friend OSWindowRef qt_mac_window_for(const QWidget *w)
Definition: qwidget_mac.mm:484
T & value() const
Returns a modifiable reference to the current item&#39;s value.
Definition: qhash.h:348
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qwidget.h:1017
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
bool isActiveWindow() const
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
The QString class provides a Unicode character string.
Definition: qstring.h:83
QFontMetrics fontMetrics
the font metrics that should be used when drawing text in the control
Definition: qstyleoption.h:91
QAction * insertMenu(QAction *before, QMenu *menu)
This convenience function inserts menu before action before and returns the menus menuAction()...
Definition: qmenu.cpp:1597
void setHeight(int h)
Sets the height to the given height.
Definition: qsize.h:135
T * qobject_cast(QObject *object)
Definition: qobject.h:375
QAction * addAction(const QString &text)
This convenience function creates a new action with text.
Definition: qmenu.cpp:1453
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define X11
Definition: qt_x11_p.h:724
#define Q_D(Class)
Definition: qglobal.h:2482
bool isTearOffEnabled() const
Definition: qmenu.cpp:1672
int height() const
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
void aboutToHide()
This signal is emitted just before the menu is hidden from the user.
uint tornoff
Definition: qmenu_p.h:272
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
uint itemsDirty
Definition: qmenu_p.h:190
QString text
the text for the menu item
Definition: qstyleoption.h:450
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
const QPoint & pos() const
Returns the position of the mouse cursor, relative to the widget that received the event...
Definition: qevent.h:95
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
QStyle * style() const
Definition: qwidget.cpp:2742
virtual QList< QPointer< QWidget > > calcCausedStack() const
Definition: qmenu.cpp:224
void hideTearOffMenu()
This function will forcibly hide the torn off menu making it disappear from the users desktop...
Definition: qmenu.cpp:1697
#define Q_Q(Class)
Definition: qglobal.h:2483
QAction * defaultAction() const
Returns the current default action.
Definition: qmenu.cpp:1637
bool isVisible() const
Definition: qaction.cpp:1246
void setWidth(int w)
Sets the width to the given width.
Definition: qsize.h:132
QPoint adjustedMenuPosition()
QPoint mousePopupPos
Definition: qmenu_p.h:209
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
QRect boundingRect(QChar) const
Returns the rectangle that is covered by ink if character ch were to be drawn at the origin of the co...
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
Definition: qevent.cpp:999
void setCurrentColorGroup(ColorGroup cg)
Set the palette&#39;s current color group to cg.
Definition: qpalette.h:105
int key() const
Returns the code of the key that was pressed or released.
Definition: qevent.h:231
#define SIGNAL(a)
Definition: qobjectdefs.h:227
QFont resolve(const QFont &) const
Returns a new QFont that has attributes copied from other that have not been previously set on this f...
Definition: qfont.cpp:1983
void setWindowTitle(const QString &)
Definition: qwidget.cpp:6312
int lineWidth
the line width for drawing the frame
Definition: qstyleoption.h:124
int width() const
Returns the width.
Definition: qsize.h:126
static QAction * createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget)
Creates a QAction and registers the &#39;triggered&#39; signal to send the given key event to actionWidget as...
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
bool isIconVisibleInMenu() const
Definition: qaction.cpp:1651
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static QMacWindowFader * currentFader()
bool isEmpty() const
Returns true if there are no visible actions inserted into the menu, false otherwise.
Definition: qmenu.cpp:1737
void triggered(QAction *action)
This signal is emitted when an action in this menu is triggered.
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
void destroyed(QObject *=0)
This signal is emitted immediately before the object obj is destroyed, and can not be blocked...
void mouseReleaseEvent(QMouseEvent *)
Reimplemented Function
Definition: qmenu.cpp:2384
The QEventLoop class provides a means of entering and leaving an event loop.
Definition: qeventloop.h:55
QSize adjustMenuSizeForScreen(const QRect &screen)
Definition: qmenu.cpp:391
QMenu(QWidget *parent=0)
Constructs a menu with parent parent.
Definition: qmenu.cpp:1386
bool visible
whether the widget is visible
Definition: qwidget.h:191
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
void setTitle(const QString &title)
Definition: qmenu.cpp:732
void leaveEvent(QEvent *)
Reimplemented Function
Definition: qmenu.cpp:2933
void qScrollEffect(QWidget *w, QEffects::DirFlags orient, int time)
Scroll widget w in time ms.
Definition: qeffects.cpp:562
The QStyleOption class stores the parameters used by QStyle functions.
Definition: qstyleoption.h:67
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
Definition: qregion.cpp:4098
~QMenu()
Destroys the menu.
Definition: qmenu.cpp:1422
int width() const
void initFrom(const QWidget *w)
Definition: qstyleoption.h:99
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
QHash< QAction *, QWidget * > widgetItems
Definition: qmenu_p.h:195
void syncWithMenu(QMenu *menu, QActionEvent *act)
Definition: qmenu.cpp:132
bool checked
whether the menu item is checked or not
Definition: qstyleoption.h:447
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
void setDefaultAction(QAction *)
This sets the default action to act.
Definition: qmenu.cpp:1627
void setFadeDuration(float durationInSecs)
Definition: qt_mac_p.h:136
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
int scrollerHeight() const
Definition: qmenu.cpp:188
#define emit
Definition: qobjectdefs.h:76
virtual void changeEvent(QEvent *)
This event handler can be reimplemented to handle state changes.
Definition: qwidget.cpp:9170
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition: qicon.cpp:769
bool separatorsCollapsible() const
The QHideEvent class provides an event which is sent after a widget is hidden.
Definition: qevent.h:388
QAction * menuAction
Definition: qmenu_p.h:285
const QPalette & palette() const
QAction * actionAt(const QPoint &) const
Returns the item at pt; returns 0 if there is no item there.
Definition: qmenu.cpp:1787
void mousePressEvent(QMouseEvent *)
Reimplemented Function
Definition: qmenu.cpp:2360
QFont font
the action&#39;s font
Definition: qaction.h:81
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const =0
Draws the given primitive element with the provided painter using the style options specified by opti...
bool hasMouseMoved(const QPoint &globalPos)
Definition: qmenu.cpp:1205
const char * styleHint(const QFontDef &request)
bool menuHasCheckableItems
whether the menu as a whole has checkable items or not
Definition: qstyleoption.h:448
QIcon icon
the action&#39;s icon
Definition: qaction.h:75
int & rx()
Returns a reference to the x coordinate of this point.
Definition: qpoint.h:140
void setText(const QString &text)
Definition: qaction.cpp:860
int delta() const
Returns the distance that the wheel is rotated, in eighths of a degree.
Definition: qevent.h:150
QAction * addSeparator()
This convenience function creates a new separator action, i.e.
Definition: qmenu.cpp:1583
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
Definition: qcoreevent.h:346
void popupAction(QAction *, int, bool)
Definition: qmenu.cpp:518
The QStyleOptionFrame class is used to describe the parameters for drawing a frame.
Definition: qstyleoption.h:118
unsigned int uint
Definition: qglobal.h:996
static const qreal MenuFadeTimeInSec
Definition: qmenu.cpp:432
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
uint maxIconWidth
Definition: qmenu_p.h:191
QAction * action() const
Returns the action that is changed, added, or removed.
Definition: qevent.h:639
short leftmargin
Definition: qwidget_p.h:744
static bool inWhatsThisMode()
Returns true if the user interface is in "What&#39;s This?" mode; otherwise returns false.
Definition: qwhatsthis.cpp:648
QString windowTitle() const
QChar toUpper() const
Returns the uppercase equivalent if the character is lowercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1287
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
void actionEvent(QActionEvent *)
Reimplemented Function
Definition: qmenu.cpp:2969
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
static int startDragDistance()
const Key & key() const
Returns the current item&#39;s key as a const reference.
Definition: qhash.h:347
QAction * sloppyAction
Definition: qmenu_p.h:279
void show()
Shows the widget and its child widgets.
MenuItemType menuItemType
the type of menu item
Definition: qstyleoption.h:445
void registerWindowToFade(QWidget *window)
void addActions(QList< QAction *> actions)
Appends the actions actions to this widget&#39;s list of actions.
Definition: qwidget.cpp:3327
bool isEmpty() const
Returns true if the key sequence is empty; otherwise returns false.
void mouseMoveEvent(QMouseEvent *)
Reimplemented Function
Definition: qmenu.cpp:2887
void setMask(const QBitmap &)
Causes only the pixels of the widget for which bitmap has a corresponding 1 bit to be visible...
Definition: qwidget.cpp:13309
bool mouseEventTaken(QMouseEvent *)
Definition: qmenu.cpp:958
Qt::MouseButton button() const
Returns the button that caused the event.
Definition: qevent.h:101
uint ncols
Definition: qmenu_p.h:200
QRect rect() const
void setEnabled(bool)
Definition: qwidget.cpp:3447
void clear()
Removes all the menu&#39;s actions.
Definition: qmenu.cpp:1755
#define Q_OBJECT
Definition: qobjectdefs.h:157
bool contains(const QPoint &p, bool proper=false) const
Returns true if the given point is inside or on the edge of the rectangle, otherwise returns false...
Definition: qrect.cpp:1101
bool isEnabled() const
Definition: qwidget.h:948
uint tearoffHighlighted
Definition: qmenu_p.h:272
virtual void setVisible(bool visible)
Definition: qwidget.cpp:7991
void moveTopLeft(const QPoint &p)
Moves the rectangle, leaving the top-left corner at the given position.
Definition: qrect.h:368
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
void hideUpToMenuBar()
Definition: qmenu.cpp:435
QMenuCaused causedPopup
Definition: qmenu_p.h:263
void stop()
Stops the timer.
static bool isActive()
Returns true if an accessibility implementation has been requested during the runtime of the applicat...
void setMouseTracking(bool enable)
Definition: qwidget.h:990
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:85
void _q_actionTriggered()
Definition: qmenu.cpp:1152
Q_CORE_EXPORT QTextStream & center(QTextStream &s)
static QDesktopWidget * desktop()
Returns the desktop widget (also called the root window).
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w=0) const =0
Returns the size of the element described by the specified option and type, based on the provided con...
const QPoint & pos() const
Returns the position of the mouse cursor relative to the widget that received the event...
Definition: qevent.h:151
QAction * exec()
Executes this menu synchronously.
Definition: qmenu.cpp:2101
QPalette palette
the palette that should be used when painting the control
Definition: qstyleoption.h:92
QPoint center() const
Returns the center point of the rectangle.
Definition: qrect.h:300
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
Definition: qobject.cpp:2895
The QWidgetAction class extends QAction by an interface for inserting custom widgets into action base...
Definition: qwidgetaction.h:57
QPointer< QMenuBar > qmenubar
Definition: qmenu_mac.mm:98
QTornOffMenu(QMenu *p)
Definition: qmenu.cpp:114
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
bool isTearOffMenuVisible() const
When a menu is torn off a second menu is shown to display the menu contents in a new window...
Definition: qmenu.cpp:1684
bool event(QEvent *)
Reimplemented Function
Definition: qmenu.cpp:2447
void setFocus()
Gives the keyboard input focus to this widget (or its focus proxy) if this widget or one of its paren...
Definition: qwidget.h:432
The QStyleHintReturnMask class provides style hints that return a QRegion.
Definition: qstyleoption.h:923
void setY(int y)
Sets the y coordinate of this point to the given y coordinate.
Definition: qpoint.h:137
QMenu * menu() const
Returns the menu contained by this action.
Definition: qaction.cpp:793
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
void aboutToShow()
This signal is emitted just before the menu is shown to the user.
void hideMenu(QMenu *menu, bool justRegister=false)
Definition: qmenu.cpp:471
static bool isEffectEnabled(Qt::UIEffect)
Returns true if effect is enabled; otherwise returns false.
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
const QRect screenGeometry(int screen=-1) const
The QMenuBar class provides a horizontal menu bar.
Definition: qmenubar.h:62
static QWidget * activePopupWidget()
Returns the active popup widget.
QList< QPointer< QWidget > > causedStack
Definition: qmenu.cpp:111
The QKeySequence class encapsulates a key sequence as used by shortcuts.
Definition: qkeysequence.h:72
void setOverrideMenuAction(QAction *)
Definition: qmenu.cpp:673
Qt::MouseButtons buttons() const
Returns the button state when the event was generated.
Definition: qevent.h:102
void setClipRegion(const QRegion &, Qt::ClipOperation op=Qt::ReplaceClip)
Sets the clip region to the given region using the specified clip operation.
Definition: qpainter.cpp:2917
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
int indexOf(const T &t, int from=0) const
Returns the index position of the first occurrence of value in the list, searching forward from index...
Definition: qlist.h:847
The QMenu class provides a menu widget for use in menu bars, context menus, and other popup menus...
Definition: qmenu.h:72
int x() const
void resize(int w, int h)
This corresponds to resize(QSize(w, h)).
Definition: qwidget.h:1014
The QTimerEvent class contains parameters that describe a timer event.
Definition: qcoreevent.h:341
QEventLoop * eventLoop
Definition: qmenu_p.h:246
void setFixedSize(const QSize &)
Sets both the minimum and maximum sizes of the widget to s, thereby preventing it from ever growing o...
Definition: qwidget.cpp:4284
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
QString text() const
Returns the Unicode text that this key generated.
Definition: qevent.h:236
QRect actionRect(QAction *) const
Definition: qmenu.cpp:419
int midLineWidth
the mid-line width for drawing the frame
Definition: qstyleoption.h:125
uint aboutToHide
Definition: qmenu_p.h:211
int tabWidth
the tab width for the menu item
Definition: qstyleoption.h:453
void onTrigger(QAction *action)
Definition: qmenu.cpp:148
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
void setRect(int x, int y, int w, int h)
Sets the coordinates of the rectangle&#39;s top-left corner to ({x}, {y}), and its size to the given widt...
Definition: qrect.h:400
void setIcon(const QIcon &icon)
Definition: qmenu.cpp:754
void removeAction(QAction *action)
Removes the action action from this widget&#39;s list of actions.
Definition: qwidget.cpp:3386
QAction * currentAction
Definition: qmenu_p.h:213
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
int key
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
bool singleShot
This static function calls a slot after a given time interval.
Definition: qtimer.h:59
void timerEvent(QTimerEvent *)
Reimplemented Function
Definition: qmenu.cpp:2947
The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
Definition: qhash.h:330
virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=0) const =0
Draws the given element with the provided painter with the style options specified by option...
void setFirstActionActive()
Definition: qmenu.cpp:552
QString title() const
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
void setTearOffEnabled(bool)
Definition: qmenu.cpp:1658
QString whatsThis
the action&#39;s "What&#39;s This?" help text
Definition: qaction.h:80
bool isCheckable() const
Definition: qaction.cpp:1105
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI...
Definition: qstyle.h:68
QList< QAction * > actions() const
Returns the (possibly empty) list of this widget&#39;s actions.
Definition: qwidget.cpp:3407
void insertAction(QAction *before, QAction *action)
Inserts the action action to this widget&#39;s list of actions, before the action before.
Definition: qwidget.cpp:3342
int & rheight()
Returns a reference to the height.
Definition: qsize.h:144
void setWidth(int w)
Sets the width of the rectangle to the given width.
Definition: qrect.h:442
int height() const
Returns the height.
Definition: qsize.h:129
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
Definition: qnamespace.h:54
QAction * addMenu(QMenu *menu)
This convenience function adds menu as a submenu to this menu.
Definition: qmenu.cpp:1541
QList< QAction * > actions
Definition: qwidget_p.h:760
void setIcon(const QIcon &icon)
Definition: qaction.cpp:772
bool isChecked() const
Definition: qaction.cpp:1151
void wheelEvent(QWheelEvent *)
Reimplemented Function
Definition: qmenu.cpp:2348
CheckType checkType
the type of checkmark of the menu item
Definition: qstyleoption.h:446
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
int getLastVisibleAction() const
Definition: qmenu.cpp:402
quint16 index
QPoint mapFromGlobal(const QPoint &) const
Translates the global screen coordinate pos to widget coordinates.
QVector< QRect > actionRects
Definition: qmenu_p.h:194
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
QObject * parent
Definition: qobject.h:92
void createWinId()
Definition: qwidget.cpp:2626
void triggered(QAction *action)
This signal is emitted when an action in a menu belonging to this menubar is triggered as a result of...
void onHovered(QAction *action)
Definition: qmenu.cpp:149
QPointer< QTornOffMenu > tornPopup
Definition: qmenu_p.h:273
void ignore()
Clears the accept flag parameter of the event object, the equivalent of calling setAccepted(false).
Definition: qcoreevent.h:310
void accept()
Sets the accept flag of the event object, the equivalent of calling setAccepted(true).
Definition: qcoreevent.h:309
const QFont & font() const
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
#define Q_DECLARE_PRIVATE(Class)
Definition: qglobal.h:2467
bool isRightToLeft() const
Definition: qwidget.h:428
bool intersects(const QRect &r) const
Returns true if this rectangle intersects with the given rectangle (i.
Definition: qrect.cpp:1429
bool close()
Closes this widget.
Definition: qwidget.cpp:8305
QAction * menuAction() const
Returns the action associated with this menu.
Definition: qmenu.cpp:711
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
QString whatsThis
Definition: qwidget_p.h:734
const QRect availableGeometry(int screen=-1) const
void updateLayoutDirection()
Definition: qmenu.cpp:691
QActionGroup * actionGroup() const
Returns the action group for this action.
Definition: qaction.cpp:747
bool event(QEvent *)
This is the main event handler; it handles event event.
Definition: qwidget.cpp:8636
void initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const
Initialize option with the values from this menu and information from action.
Definition: qmenu.cpp:1222
QRegion region
the region for style hints that return a QRegion
Definition: qstyleoption.h:930
QPointer< QAction > actionAboutToTrigger
Definition: qmenu_p.h:338
void paintEvent(QPaintEvent *)
Reimplemented Function
Definition: qmenu.cpp:2249
QWidget * topCausedWidget() const
Definition: qmenu.cpp:653
void moveTop(int pos)
Moves the rectangle vertically, leaving the rectangle&#39;s top edge at the given y coordinate.
Definition: qrect.h:353
bool isEmpty() const
Returns true if either of the width and height is less than or equal to 0; otherwise returns false...
Definition: qsize.h:120
int columnCount() const
If a menu does not fit on the screen it lays itself out so that it does fit.
Definition: qmenu.cpp:1779
#define slots
Definition: qobjectdefs.h:68
const QRect & rect() const
Returns the rectangle that needs to be updated.
Definition: qevent.h:305
int height() const
Returns the height of the font.
const QRect & geometry() const
void activateCausedStack(const QList< QPointer< QWidget > > &, QAction *, QAction::ActionEvent, bool)
Definition: qmenu.cpp:1036
static void showText(const QPoint &pos, const QString &text, QWidget *w=0)
Shows text as a "What&#39;s This?" window, at global position pos.
Definition: qwhatsthis.cpp:754
QPointer< QAction > action
Definition: qmenu_p.h:260
void releaseWidget(QWidget *widget)
Releases the specified widget.
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately before the event occurred.
Definition: qevent.h:79
The QPaintEvent class contains event parameters for paint events.
Definition: qevent.h:298
#define class
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312
void qFadeEffect(QWidget *w, int time)
Fade in widget w in time ms.
Definition: qeffects.cpp:584
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
void hideEvent(QHideEvent *)
Reimplemented Function
Definition: qmenu.cpp:2224
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
const QPoint & globalPos() const
Returns the global position of the mouse cursor at the time of the event.
Definition: qevent.h:96
void setX(int x)
Sets the x coordinate of this point to the given x coordinate.
Definition: qpoint.h:134
bool isExclusive() const
static QWidget * focusWidget()
Returns the application widget that has the keyboard input focus, or 0 if no widget in this applicati...
uint tabWidth
Definition: qmenu_p.h:191
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QPointer< QWidget > widget
Definition: qmenu_p.h:259
QPoint mapToGlobal(const QPoint &) const
Translates the widget coordinate pos to global screen coordinates.
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QRect rect
the area that should be used for various calculations and painting
Definition: qstyleoption.h:90
bool hasCheckableItems
Definition: qmenu_p.h:275
int exec(ProcessEventsFlags flags=AllEvents)
Enters the main event loop and waits until exit() is called.
Definition: qeventloop.cpp:181
void enterEvent(QEvent *)
Reimplemented Function
Definition: qmenu.cpp:2925
QRect popupGeometry(const QWidget *widget) const
Definition: qmenu.cpp:195
void _q_actionHovered()
Definition: qmenu.cpp:1187
void internalDelayedPopup()
Definition: qmenu.cpp:3048
The QAction class provides an abstract user interface action that can be inserted into widgets...
Definition: qaction.h:64
void activateAction(QAction *, QAction::ActionEvent, bool self=true)
Definition: qmenu.cpp:1085
void start(int msec, QObject *obj)
Starts (or restarts) the timer with a msec milliseconds timeout.
static void enterWhatsThisMode()
This function switches the user interface into "What&#39;s This?" mode.
Definition: qwhatsthis.cpp:633
QAction * actionAt(QPoint p) const
Definition: qmenu.cpp:661
int & rwidth()
Returns a reference to the width.
Definition: qsize.h:141
#define text
Definition: qobjectdefs.h:80
static QPoint pos()
Returns the position of the cursor (hot spot) in global screen coordinates.
Definition: qcursor_mac.mm:310
The QWeakPointer class holds a weak reference to a shared pointer.
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition: qobject.cpp:1650
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
Qt::LayoutDirection direction
void hovered(QAction *action)
This signal is emitted when a menu action is highlighted; action is the action that caused the event ...
void macWindowFade(void *window, float durationSeconds)
The QIcon class provides scalable icons in different modes and states.
Definition: qicon.h:60