source: trunk/src/gui/widgets/qmenubar.cpp@ 1119

Last change on this file since 1119 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 71.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <qmenubar.h>
43
44#include <qstyle.h>
45#include <qlayout.h>
46#include <qapplication.h>
47#include <qdesktopwidget.h>
48#ifndef QT_NO_ACCESSIBILITY
49# include <qaccessible.h>
50#endif
51#include <qpainter.h>
52#include <qstylepainter.h>
53#include <qevent.h>
54#include <qmainwindow.h>
55#include <qtoolbar.h>
56#include <qtoolbutton.h>
57#include <qwhatsthis.h>
58
59#ifndef QT_NO_MENUBAR
60
61#ifdef QT3_SUPPORT
62#include <private/qaction_p.h>
63#include <qmenudata.h>
64#endif
65
66#include "qmenu_p.h"
67#include "qmenubar_p.h"
68#include "qdebug.h"
69
70#ifdef Q_WS_WINCE
71extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp
72#endif
73
74#ifdef QT_SOFTKEYS_ENABLED
75#include <private/qsoftkeymanager_p.h>
76#endif
77
78QT_BEGIN_NAMESPACE
79
80class QMenuBarExtension : public QToolButton
81{
82public:
83 explicit QMenuBarExtension(QWidget *parent);
84
85 QSize sizeHint() const;
86 void paintEvent(QPaintEvent *);
87};
88
89QMenuBarExtension::QMenuBarExtension(QWidget *parent)
90 : QToolButton(parent)
91{
92 setObjectName(QLatin1String("qt_menubar_ext_button"));
93 setAutoRaise(true);
94#ifndef QT_NO_MENU
95 setPopupMode(QToolButton::InstantPopup);
96#endif
97 setIcon(style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton, 0, parentWidget()));
98}
99
100void QMenuBarExtension::paintEvent(QPaintEvent *)
101{
102 QStylePainter p(this);
103 QStyleOptionToolButton opt;
104 initStyleOption(&opt);
105 // We do not need to draw both extension arrows
106 opt.features &= ~QStyleOptionToolButton::HasMenu;
107 p.drawComplexControl(QStyle::CC_ToolButton, opt);
108}
109
110
111QSize QMenuBarExtension::sizeHint() const
112{
113 int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent, 0, parentWidget());
114 return QSize(ext, ext);
115}
116
117
118/*!
119 \internal
120*/
121QAction *QMenuBarPrivate::actionAt(QPoint p) const
122{
123 for(int i = 0; i < actions.size(); ++i) {
124 if(actionRect(actions.at(i)).contains(p))
125 return actions.at(i);
126 }
127 return 0;
128}
129
130QRect QMenuBarPrivate::menuRect(bool extVisible) const
131{
132 Q_Q(const QMenuBar);
133
134 int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
135 QRect result = q->rect();
136 result.adjust(hmargin, 0, -hmargin, 0);
137
138 if (extVisible) {
139 if (q->isRightToLeft())
140 result.setLeft(result.left() + extension->sizeHint().width());
141 else
142 result.setWidth(result.width() - extension->sizeHint().width());
143 }
144
145 if (leftWidget && leftWidget->isVisible()) {
146 QSize sz = leftWidget->sizeHint();
147 if (q->isRightToLeft())
148 result.setRight(result.right() - sz.width());
149 else
150 result.setLeft(result.left() + sz.width());
151 }
152
153 if (rightWidget && rightWidget->isVisible()) {
154 QSize sz = rightWidget->sizeHint();
155 if (q->isRightToLeft())
156 result.setLeft(result.left() + sz.width());
157 else
158 result.setRight(result.right() - sz.width());
159 }
160
161 return result;
162}
163
164bool QMenuBarPrivate::isVisible(QAction *action)
165{
166 return !hiddenActions.contains(action);
167}
168
169void QMenuBarPrivate::updateGeometries()
170{
171 Q_Q(QMenuBar);
172 if(!itemsDirty)
173 return;
174 int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q)*2);
175 int q_start = -1;
176 if(leftWidget || rightWidget) {
177 int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q)
178 + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
179 int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q)
180 + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
181 if (leftWidget && leftWidget->isVisible()) {
182 QSize sz = leftWidget->sizeHint();
183 q_width -= sz.width();
184 q_start = sz.width();
185 QPoint pos(hmargin, (q->height() - leftWidget->height()) / 2);
186 QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
187 leftWidget->setGeometry(vRect);
188 }
189 if (rightWidget && rightWidget->isVisible()) {
190 QSize sz = rightWidget->sizeHint();
191 q_width -= sz.width();
192 QPoint pos(q->width() - sz.width() - hmargin, vmargin);
193 QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
194 rightWidget->setGeometry(vRect);
195 }
196 }
197
198#ifdef Q_WS_MAC
199 if(q->isNativeMenuBar()) {//nothing to see here folks, move along..
200 itemsDirty = false;
201 return;
202 }
203#endif
204 calcActionRects(q_width, q_start);
205 currentAction = 0;
206#ifndef QT_NO_SHORTCUT
207 if(itemsDirty) {
208 for(int j = 0; j < shortcutIndexMap.size(); ++j)
209 q->releaseShortcut(shortcutIndexMap.value(j));
210 shortcutIndexMap.resize(0); // faster than clear
211 for(int i = 0; i < actions.count(); i++)
212 shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text())));
213 }
214#endif
215 itemsDirty = false;
216
217 hiddenActions.clear();
218 //this is the menu rectangle without any extension
219 QRect menuRect = this->menuRect(false);
220
221 //we try to see if the actions will fit there
222 bool hasHiddenActions = false;
223 for (int i = 0; i < actions.count(); ++i) {
224 const QRect &rect = actionRects.at(i);
225 if (rect.isValid() && !menuRect.contains(rect)) {
226 hasHiddenActions = true;
227 break;
228 }
229 }
230
231 //...and if not, determine the ones that fit on the menu with the extension visible
232 if (hasHiddenActions) {
233 menuRect = this->menuRect(true);
234 for (int i = 0; i < actions.count(); ++i) {
235 const QRect &rect = actionRects.at(i);
236 if (rect.isValid() && !menuRect.contains(rect)) {
237 hiddenActions.append(actions.at(i));
238 }
239 }
240 }
241
242 if (hiddenActions.count() > 0) {
243 QMenu *pop = extension->menu();
244 if (!pop) {
245 pop = new QMenu(q);
246 extension->setMenu(pop);
247 }
248 pop->clear();
249 pop->addActions(hiddenActions);
250
251 int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q);
252 int x = q->isRightToLeft()
253 ? menuRect.left() - extension->sizeHint().width() + 1
254 : menuRect.right();
255 extension->setGeometry(x, vmargin, extension->sizeHint().width(), menuRect.height() - vmargin*2);
256 extension->show();
257 } else {
258 extension->hide();
259 }
260 q->updateGeometry();
261#ifdef QT3_SUPPORT
262 if (parent) {
263 QMenubarUpdatedEvent menubarUpdated(q);
264 QApplication::sendEvent(parent, &menubarUpdated);
265 }
266#endif
267}
268
269QRect QMenuBarPrivate::actionRect(QAction *act) const
270{
271 const int index = actions.indexOf(act);
272
273 //makes sure the geometries are up-to-date
274 const_cast<QMenuBarPrivate*>(this)->updateGeometries();
275
276 if (index < 0 || index >= actionRects.count())
277 return QRect(); // that can happen in case of native menubar
278
279 return actionRects.at(index);
280}
281
282void QMenuBarPrivate::focusFirstAction()
283{
284 if(!currentAction) {
285 updateGeometries();
286 int index = 0;
287 while (index < actions.count() && actionRects.at(index).isNull()) ++index;
288 if (index < actions.count())
289 setCurrentAction(actions.at(index));
290 }
291}
292
293void QMenuBarPrivate::setKeyboardMode(bool b)
294{
295 Q_Q(QMenuBar);
296 if (b && !q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {
297 setCurrentAction(0);
298 return;
299 }
300 keyboardState = b;
301 if(b) {
302 QWidget *fw = QApplication::focusWidget();
303 if (fw != q)
304 keyboardFocusWidget = fw;
305 focusFirstAction();
306 q->setFocus(Qt::MenuBarFocusReason);
307 } else {
308 if(!popupState)
309 setCurrentAction(0);
310 if(keyboardFocusWidget) {
311 if (QApplication::focusWidget() == q)
312 keyboardFocusWidget->setFocus(Qt::MenuBarFocusReason);
313 keyboardFocusWidget = 0;
314 }
315 }
316 q->update();
317}
318
319void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
320{
321 Q_Q(QMenuBar);
322 if(!action || !action->menu() || closePopupMode)
323 return;
324 popupState = true;
325 if (action->isEnabled() && action->menu()->isEnabled()) {
326 closePopupMode = 0;
327 activeMenu = action->menu();
328 activeMenu->d_func()->causedPopup.widget = q;
329 activeMenu->d_func()->causedPopup.action = action;
330
331 QRect adjustedActionRect = actionRect(action);
332 QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
333 QSize popup_size = activeMenu->sizeHint();
334
335 //we put the popup menu on the screen containing the bottom-center of the action rect
336 QRect screenRect = QApplication::desktop()->screenGeometry(pos + QPoint(adjustedActionRect.width() / 2, 0));
337 pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
338
339 const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height());
340 const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
341 const bool rtl = q->isRightToLeft();
342 const int actionWidth = adjustedActionRect.width();
343
344 if (!fitUp && !fitDown) { //we should shift the menu
345 bool shouldShiftToRight = !rtl;
346 if (rtl && popup_size.width() > pos.x())
347 shouldShiftToRight = true;
348 else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())
349 shouldShiftToRight = false;
350
351 if (shouldShiftToRight) {
352 pos.rx() += actionWidth + (rtl ? popup_size.width() : 0);
353 } else {
354 //shift to left
355 if (!rtl)
356 pos.rx() -= popup_size.width();
357 }
358 } else if (rtl) {
359 pos.rx() += actionWidth;
360 }
361
362 if(!defaultPopDown || (fitUp && !fitDown))
363 pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y()));
364 activeMenu->popup(pos);
365 if(activateFirst)
366 activeMenu->d_func()->setFirstActionActive();
367 }
368 q->update(actionRect(action));
369}
370
371void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activateFirst)
372{
373 if(currentAction == action && popup == popupState)
374 return;
375
376 autoReleaseTimer.stop();
377
378 doChildEffects = (popup && !activeMenu);
379 Q_Q(QMenuBar);
380 QWidget *fw = 0;
381 if(QMenu *menu = activeMenu) {
382 activeMenu = 0;
383 if (popup) {
384 fw = q->window()->focusWidget();
385 q->setFocus(Qt::NoFocusReason);
386 }
387 menu->hide();
388 }
389
390 if(currentAction)
391 q->update(actionRect(currentAction));
392
393 popupState = popup;
394#ifndef QT_NO_STATUSTIP
395 QAction *previousAction = currentAction;
396#endif
397 currentAction = action;
398 if (action) {
399 activateAction(action, QAction::Hover);
400 if(popup)
401 popupAction(action, activateFirst);
402 q->update(actionRect(action));
403#ifndef QT_NO_STATUSTIP
404 } else if (previousAction) {
405 QString empty;
406 QStatusTipEvent tip(empty);
407 QApplication::sendEvent(q, &tip);
408#endif
409 }
410 if (fw)
411 fw->setFocus(Qt::NoFocusReason);
412}
413
414void QMenuBarPrivate::calcActionRects(int max_width, int start) const
415{
416 Q_Q(const QMenuBar);
417
418 if(!itemsDirty)
419 return;
420
421 //let's reinitialize the buffer
422 actionRects.resize(actions.count());
423 actionRects.fill(QRect());
424
425 const QStyle *style = q->style();
426
427 const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q);
428 int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0;
429
430 //calculate size
431 const QFontMetrics fm = q->fontMetrics();
432 const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q),
433 vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q),
434 icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
435 for(int i = 0; i < actions.count(); i++) {
436 QAction *action = actions.at(i);
437 if(!action->isVisible())
438 continue;
439
440 QSize sz;
441
442 //calc what I think the size is..
443 if(action->isSeparator()) {
444 if (style->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q))
445 separator = i;
446 continue; //we don't really position these!
447 } else {
448 const QString s = action->text();
449 QIcon is = action->icon();
450 // If an icon is set, only the icon is visible
451 if (!is.isNull())
452 sz = sz.expandedTo(QSize(icone, icone));
453 else if (!s.isEmpty())
454 sz = fm.size(Qt::TextShowMnemonic, s);
455 }
456
457 //let the style modify the above size..
458 QStyleOptionMenuItem opt;
459 q->initStyleOption(&opt, action);
460 sz = q->style()->sizeFromContents(QStyle::CT_MenuBarItem, &opt, sz, q);
461
462 if(!sz.isEmpty()) {
463 { //update the separator state
464 int iWidth = sz.width() + itemSpacing;
465 if(separator == -1)
466 separator_start += iWidth;
467 else
468 separator_len += iWidth;
469 }
470 //maximum height
471 max_item_height = qMax(max_item_height, sz.height());
472 //append
473 actionRects[i] = QRect(0, 0, sz.width(), sz.height());
474 }
475 }
476
477 //calculate position
478 const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
479 int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
480 int y = fw + vmargin;
481 for(int i = 0; i < actions.count(); i++) {
482 QRect &rect = actionRects[i];
483 if (rect.isNull())
484 continue;
485
486 //resize
487 rect.setHeight(max_item_height);
488
489 //move
490 if(separator != -1 && i >= separator) { //after the separator
491 int left = (max_width - separator_len - hmargin - itemSpacing) + (x - separator_start - hmargin);
492 if(left < separator_start) { //wrap
493 separator_start = x = hmargin;
494 y += max_item_height;
495 }
496 rect.moveLeft(left);
497 } else {
498 rect.moveLeft(x);
499 }
500 rect.moveTop(y);
501
502 //keep moving along..
503 x += rect.width() + itemSpacing;
504
505 //make sure we follow the layout direction
506 rect = QStyle::visualRect(q->layoutDirection(), q->rect(), rect);
507 }
508}
509
510void QMenuBarPrivate::activateAction(QAction *action, QAction::ActionEvent action_e)
511{
512 Q_Q(QMenuBar);
513 if (!action || !action->isEnabled())
514 return;
515 action->activate(action_e);
516 if (action_e == QAction::Hover)
517 action->showStatusText(q);
518
519// if(action_e == QAction::Trigger)
520// emit q->activated(action);
521// else if(action_e == QAction::Hover)
522// emit q->highlighted(action);
523}
524
525
526void QMenuBarPrivate::_q_actionTriggered()
527{
528 Q_Q(QMenuBar);
529 if (QAction *action = qobject_cast<QAction *>(q->sender())) {
530 emit q->triggered(action);
531#ifdef QT3_SUPPORT
532 emit q->activated(q->findIdForAction(action));
533#endif
534 }
535}
536
537void QMenuBarPrivate::_q_actionHovered()
538{
539 Q_Q(QMenuBar);
540 if (QAction *action = qobject_cast<QAction *>(q->sender())) {
541 emit q->hovered(action);
542#ifndef QT_NO_ACCESSIBILITY
543 if (QAccessible::isActive()) {
544 int actionIndex = actions.indexOf(action);
545 ++actionIndex;
546 QAccessible::updateAccessibility(q, actionIndex, QAccessible::Focus);
547 QAccessible::updateAccessibility(q, actionIndex, QAccessible::Selection);
548 }
549#endif //QT_NO_ACCESSIBILITY
550#ifdef QT3_SUPPORT
551 emit q->highlighted(q->findIdForAction(action));
552#endif
553 }
554}
555
556/*!
557 Initialize \a option with the values from the menu bar and information from \a action. This method
558 is useful for subclasses when they need a QStyleOptionMenuItem, but don't want
559 to fill in all the information themselves.
560
561 \sa QStyleOption::initFrom() QMenu::initStyleOption()
562*/
563void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const
564{
565 if (!option || !action)
566 return;
567 Q_D(const QMenuBar);
568 option->palette = palette();
569 option->state = QStyle::State_None;
570 if (isEnabled() && action->isEnabled())
571 option->state |= QStyle::State_Enabled;
572 else
573 option->palette.setCurrentColorGroup(QPalette::Disabled);
574 option->fontMetrics = fontMetrics();
575 if (d->currentAction && d->currentAction == action) {
576 option->state |= QStyle::State_Selected;
577 if (d->popupState && !d->closePopupMode)
578 option->state |= QStyle::State_Sunken;
579 }
580 if (hasFocus() || d->currentAction)
581 option->state |= QStyle::State_HasFocus;
582 option->menuRect = rect();
583 option->menuItemType = QStyleOptionMenuItem::Normal;
584 option->checkType = QStyleOptionMenuItem::NotCheckable;
585 option->text = action->text();
586 option->icon = action->icon();
587}
588
589/*!
590 \class QMenuBar
591 \brief The QMenuBar class provides a horizontal menu bar.
592
593 \ingroup mainwindow-classes
594
595 A menu bar consists of a list of pull-down menu items. You add
596 menu items with addMenu(). For example, asuming that \c menubar
597 is a pointer to a QMenuBar and \c fileMenu is a pointer to a
598 QMenu, the following statement inserts the menu into the menu bar:
599 \snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 0
600
601 The ampersand in the menu item's text sets Alt+F as a shortcut for
602 this menu. (You can use "\&\&" to get a real ampersand in the menu
603 bar.)
604
605 There is no need to lay out a menu bar. It automatically sets its
606 own geometry to the top of the parent widget and changes it
607 appropriately whenever the parent is resized.
608
609 \section1 Usage
610
611 In most main window style applications you would use the
612 \l{QMainWindow::}{menuBar()} function provided in QMainWindow,
613 adding \l{QMenu}s to the menu bar and adding \l{QAction}s to the
614 pop-up menus.
615
616 Example (from the \l{mainwindows/menus}{Menus} example):
617
618 \snippet examples/mainwindows/menus/mainwindow.cpp 9
619
620 Menu items may be removed with removeAction().
621
622 Widgets can be added to menus by using instances of the QWidgetAction
623 class to hold them. These actions can then be inserted into menus
624 in the usual way; see the QMenu documentation for more details.
625
626 \section1 Platform Dependent Look and Feel
627
628 Different platforms have different requirements for the appearance
629 of menu bars and their behavior when the user interacts with them.
630 For example, Windows systems are often configured so that the
631 underlined character mnemonics that indicate keyboard shortcuts
632 for items in the menu bar are only shown when the \gui{Alt} key is
633 pressed.
634
635 \table
636
637 \row \o \inlineimage plastique-menubar.png A menu bar shown in the
638 Plastique widget style.
639
640 \o The \l{QPlastiqueStyle}{Plastique widget style}, like most
641 other styles, handles the \gui{Help} menu in the same way as it
642 handles any other menu.
643
644 \row \o \inlineimage motif-menubar.png A menu bar shown in the
645 Motif widget style.
646
647 \o The \l{QMotifStyle}{Motif widget style} treats \gui{Help} menus
648 in a special way, placing them at right-hand end of the menu bar.
649
650 \endtable
651
652 \section1 QMenuBar on Mac OS X
653
654 QMenuBar on Mac OS X is a wrapper for using the system-wide menu bar.
655 If you have multiple menu bars in one dialog the outermost menu bar
656 (normally inside a widget with widget flag Qt::Window) will
657 be used for the system-wide menu bar.
658
659 Qt for Mac OS X also provides a menu bar merging feature to make
660 QMenuBar conform more closely to accepted Mac OS X menu bar layout.
661 The merging functionality is based on string matching the title of
662 a QMenu entry. These strings are translated (using QObject::tr())
663 in the "QMenuBar" context. If an entry is moved its slots will still
664 fire as if it was in the original place. The table below outlines
665 the strings looked for and where the entry is placed if matched:
666
667 \table
668 \header \i String matches \i Placement \i Notes
669 \row \i about.*
670 \i Application Menu | About <application name>
671 \i The application name is fetched from the \c {Info.plist} file
672 (see note below). If this entry is not found no About item
673 will appear in the Application Menu.
674 \row \i config, options, setup, settings or preferences
675 \i Application Menu | Preferences
676 \i If this entry is not found the Settings item will be disabled
677 \row \i quit or exit
678 \i Application Menu | Quit <application name>
679 \i If this entry is not found a default Quit item will be
680 created to call QApplication::quit()
681 \endtable
682
683 You can override this behavior by using the QAction::menuRole()
684 property.
685
686 If you want all windows in a Mac application to share one menu
687 bar, you must create a menu bar that does not have a parent.
688 Create a parent-less menu bar this way:
689
690 \snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 1
691
692 \bold{Note:} Do \e{not} call QMainWindow::menuBar() to create the
693 shared menu bar, because that menu bar will have the QMainWindow
694 as its parent. That menu bar would only be displayed for the
695 parent QMainWindow.
696
697 \bold{Note:} The text used for the application name in the menu
698 bar is obtained from the value set in the \c{Info.plist} file in
699 the application's bundle. See \l{Deploying an Application on
700 Mac OS X} for more information.
701
702 \section1 QMenuBar on Windows CE
703
704 QMenuBar on Windows CE is a wrapper for using the system-wide menu bar,
705 similar to the Mac. This feature is activated for Windows Mobile
706 and integrates QMenuBar with the native soft keys. The left soft
707 key can be controlled with QMenuBar::setDefaultAction() and the
708 right soft key can be used to access the menu bar.
709
710 The hovered() signal is not supported for the native menu
711 integration. Also, it is not possible to display an icon in a
712 native menu on Windows Mobile.
713
714 \section1 Examples
715
716 The \l{mainwindows/menus}{Menus} example shows how to use QMenuBar
717 and QMenu. The other \l{Main Window Examples}{main window
718 application examples} also provide menus using these classes.
719
720 \sa QMenu, QShortcut, QAction,
721 {http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGIntro/XHIGIntro.html}{Introduction to Apple Human Interface Guidelines},
722 {fowler}{GUI Design Handbook: Menu Bar}, {Menus Example}
723*/
724
725
726void QMenuBarPrivate::init()
727{
728 Q_Q(QMenuBar);
729 q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
730 q->setAttribute(Qt::WA_CustomWhatsThis);
731#ifdef Q_WS_MAC
732 macCreateMenuBar(q->parentWidget());
733 if(mac_menubar)
734 q->hide();
735#endif
736#ifdef Q_WS_WINCE
737 if (qt_wince_is_mobile()) {
738 wceCreateMenuBar(q->parentWidget());
739 if(wce_menubar)
740 q->hide();
741 }
742 else {
743 QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
744 }
745#endif
746 q->setBackgroundRole(QPalette::Button);
747 oldWindow = oldParent = 0;
748#ifdef QT3_SUPPORT
749 doAutoResize = false;
750#endif
751#ifdef QT_SOFTKEYS_ENABLED
752 menuBarAction = 0;
753#endif
754 handleReparent();
755 q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, q));
756
757 extension = new QMenuBarExtension(q);
758 extension->setFocusPolicy(Qt::NoFocus);
759 extension->hide();
760}
761
762//Gets the next action for keyboard navigation
763QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const
764{
765 Q_Q(const QMenuBar);
766 const_cast<QMenuBarPrivate*>(this)->updateGeometries();
767 bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q);
768 const int start = (_start == -1 && increment == -1) ? actions.count() : _start;
769 const int end = increment == -1 ? 0 : actions.count() - 1;
770
771 for (int i = start; i != end;) {
772 i += increment;
773 QAction *current = actions.at(i);
774 if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled()))
775 return current;
776 }
777
778 if (_start != -1) //let's try from the beginning or the end
779 return getNextAction(-1, increment);
780
781 return 0;
782}
783
784/*!
785 Constructs a menu bar with parent \a parent.
786*/
787QMenuBar::QMenuBar(QWidget *parent) : QWidget(*new QMenuBarPrivate, parent, 0)
788{
789 Q_D(QMenuBar);
790 d->init();
791}
792
793#ifdef QT3_SUPPORT
794/*!
795 Use one of the constructors that doesn't take the \a name
796 argument and then use setObjectName() instead.
797*/
798QMenuBar::QMenuBar(QWidget *parent, const char *name) : QWidget(*new QMenuBarPrivate, parent, 0)
799{
800 Q_D(QMenuBar);
801 d->init();
802 setObjectName(QString::fromAscii(name));
803}
804#endif
805
806/*!
807 Destroys the menu bar.
808*/
809QMenuBar::~QMenuBar()
810{
811#ifdef Q_WS_MAC
812 Q_D(QMenuBar);
813 d->macDestroyMenuBar();
814#endif
815#ifdef Q_WS_WINCE
816 Q_D(QMenuBar);
817 if (qt_wince_is_mobile())
818 d->wceDestroyMenuBar();
819#endif
820#ifdef Q_WS_S60
821 Q_D(QMenuBar);
822 d->symbianDestroyMenuBar();
823#endif
824}
825
826/*!
827 \overload
828
829 This convenience function creates a new action with \a text.
830 The function adds the newly created action to the menu's
831 list of actions, and returns it.
832
833 \sa QWidget::addAction(), QWidget::actions()
834*/
835QAction *QMenuBar::addAction(const QString &text)
836{
837 QAction *ret = new QAction(text, this);
838 addAction(ret);
839 return ret;
840}
841
842/*!
843 \overload
844
845 This convenience function creates a new action with the given \a
846 text. The action's triggered() signal is connected to the \a
847 receiver's \a member slot. The function adds the newly created
848 action to the menu's list of actions and returns it.
849
850 \sa QWidget::addAction(), QWidget::actions()
851*/
852QAction *QMenuBar::addAction(const QString &text, const QObject *receiver, const char* member)
853{
854 QAction *ret = new QAction(text, this);
855 QObject::connect(ret, SIGNAL(triggered(bool)), receiver, member);
856 addAction(ret);
857 return ret;
858}
859
860/*!
861 Appends a new QMenu with \a title to the menu bar. The menu bar
862 takes ownership of the menu. Returns the new menu.
863
864 \sa QWidget::addAction() QMenu::menuAction()
865*/
866QMenu *QMenuBar::addMenu(const QString &title)
867{
868 QMenu *menu = new QMenu(title, this);
869 addAction(menu->menuAction());
870 return menu;
871}
872
873/*!
874 Appends a new QMenu with \a icon and \a title to the menu bar. The menu bar
875 takes ownership of the menu. Returns the new menu.
876
877 \sa QWidget::addAction() QMenu::menuAction()
878*/
879QMenu *QMenuBar::addMenu(const QIcon &icon, const QString &title)
880{
881 QMenu *menu = new QMenu(title, this);
882 menu->setIcon(icon);
883 addAction(menu->menuAction());
884 return menu;
885}
886
887/*!
888 Appends \a menu to the menu bar. Returns the menu's menuAction().
889
890 \note The returned QAction object can be used to hide the corresponding
891 menu.
892
893 \sa QWidget::addAction() QMenu::menuAction()
894*/
895QAction *QMenuBar::addMenu(QMenu *menu)
896{
897 QAction *action = menu->menuAction();
898 addAction(action);
899 return action;
900}
901
902/*!
903 Appends a separator to the menu.
904*/
905QAction *QMenuBar::addSeparator()
906{
907 QAction *ret = new QAction(this);
908 ret->setSeparator(true);
909 addAction(ret);
910 return ret;
911}
912
913/*!
914 This convenience function creates a new separator action, i.e. an
915 action with QAction::isSeparator() returning true. The function inserts
916 the newly created action into this menu bar's list of actions before
917 action \a before and returns it.
918
919 \sa QWidget::insertAction(), addSeparator()
920*/
921QAction *QMenuBar::insertSeparator(QAction *before)
922{
923 QAction *action = new QAction(this);
924 action->setSeparator(true);
925 insertAction(before, action);
926 return action;
927}
928
929/*!
930 This convenience function inserts \a menu before action \a before
931 and returns the menus menuAction().
932
933 \sa QWidget::insertAction() addMenu()
934*/
935QAction *QMenuBar::insertMenu(QAction *before, QMenu *menu)
936{
937 QAction *action = menu->menuAction();
938 insertAction(before, action);
939 return action;
940}
941
942/*!
943 Returns the QAction that is currently highlighted. A null pointer
944 will be returned if no action is currently selected.
945*/
946QAction *QMenuBar::activeAction() const
947{
948 Q_D(const QMenuBar);
949 return d->currentAction;
950}
951
952/*!
953 \since 4.1
954
955 Sets the currently highlighted action to \a act.
956*/
957void QMenuBar::setActiveAction(QAction *act)
958{
959 Q_D(QMenuBar);
960 d->setCurrentAction(act, true, false);
961}
962
963
964/*!
965 Removes all the actions from the menu bar.
966
967 \note On Mac OS X, menu items that have been merged to the system
968 menu bar are not removed by this function. One way to handle this
969 would be to remove the extra actions yourself. You can set the
970 \l{QAction::MenuRole}{menu role} on the different menus, so that
971 you know ahead of time which menu items get merged and which do
972 not. Then decide what to recreate or remove yourself.
973
974 \sa removeAction()
975*/
976void QMenuBar::clear()
977{
978 QList<QAction*> acts = actions();
979 for(int i = 0; i < acts.size(); i++)
980 removeAction(acts[i]);
981}
982
983/*!
984 \property QMenuBar::defaultUp
985 \brief the popup orientation
986
987 The default popup orientation. By default, menus pop "down" the
988 screen. By setting the property to true, the menu will pop "up".
989 You might call this for menus that are \e below the document to
990 which they refer.
991
992 If the menu would not fit on the screen, the other direction is
993 used automatically.
994*/
995void QMenuBar::setDefaultUp(bool b)
996{
997 Q_D(QMenuBar);
998 d->defaultPopDown = !b;
999}
1000
1001bool QMenuBar::isDefaultUp() const
1002{
1003 Q_D(const QMenuBar);
1004 return !d->defaultPopDown;
1005}
1006
1007/*!
1008 \reimp
1009*/
1010void QMenuBar::resizeEvent(QResizeEvent *)
1011{
1012 Q_D(QMenuBar);
1013 d->itemsDirty = true;
1014 d->updateGeometries();
1015}
1016
1017/*!
1018 \reimp
1019*/
1020void QMenuBar::paintEvent(QPaintEvent *e)
1021{
1022 Q_D(QMenuBar);
1023 QPainter p(this);
1024 QRegion emptyArea(rect());
1025
1026 //draw the items
1027 for (int i = 0; i < d->actions.count(); ++i) {
1028 QAction *action = d->actions.at(i);
1029 QRect adjustedActionRect = d->actionRect(action);
1030 if (adjustedActionRect.isEmpty() || !d->isVisible(action))
1031 continue;
1032 if(!e->rect().intersects(adjustedActionRect))
1033 continue;
1034
1035 emptyArea -= adjustedActionRect;
1036 QStyleOptionMenuItem opt;
1037 initStyleOption(&opt, action);
1038 opt.rect = adjustedActionRect;
1039 p.setClipRect(adjustedActionRect);
1040 style()->drawControl(QStyle::CE_MenuBarItem, &opt, &p, this);
1041 }
1042 //draw border
1043 if(int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this)) {
1044 QRegion borderReg;
1045 borderReg += QRect(0, 0, fw, height()); //left
1046 borderReg += QRect(width()-fw, 0, fw, height()); //right
1047 borderReg += QRect(0, 0, width(), fw); //top
1048 borderReg += QRect(0, height()-fw, width(), fw); //bottom
1049 p.setClipRegion(borderReg);
1050 emptyArea -= borderReg;
1051 QStyleOptionFrame frame;
1052 frame.rect = rect();
1053 frame.palette = palette();
1054 frame.state = QStyle::State_None;
1055 frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth);
1056 frame.midLineWidth = 0;
1057 style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p, this);
1058 }
1059 p.setClipRegion(emptyArea);
1060 QStyleOptionMenuItem menuOpt;
1061 menuOpt.palette = palette();
1062 menuOpt.state = QStyle::State_None;
1063 menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea;
1064 menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
1065 menuOpt.rect = rect();
1066 menuOpt.menuRect = rect();
1067 style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menuOpt, &p, this);
1068}
1069
1070/*!
1071 \reimp
1072*/
1073void QMenuBar::setVisible(bool visible)
1074{
1075#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
1076 if (isNativeMenuBar())
1077 return;
1078#endif
1079 QWidget::setVisible(visible);
1080}
1081
1082/*!
1083 \reimp
1084*/
1085void QMenuBar::mousePressEvent(QMouseEvent *e)
1086{
1087 Q_D(QMenuBar);
1088 if(e->button() != Qt::LeftButton)
1089 return;
1090
1091 d->mouseDown = true;
1092
1093 QAction *action = d->actionAt(e->pos());
1094 if (!action || !d->isVisible(action)) {
1095 d->setCurrentAction(0);
1096#ifndef QT_NO_WHATSTHIS
1097 if (QWhatsThis::inWhatsThisMode())
1098 QWhatsThis::showText(e->globalPos(), d->whatsThis, this);
1099#endif
1100 return;
1101 }
1102
1103 if(d->currentAction == action && d->popupState) {
1104 if(QMenu *menu = d->activeMenu) {
1105 d->activeMenu = 0;
1106 menu->hide();
1107 }
1108#ifdef Q_WS_WIN
1109 if((d->closePopupMode = style()->styleHint(QStyle::SH_MenuBar_DismissOnSecondClick)))
1110 update(d->actionRect(action));
1111#endif
1112 } else {
1113 d->setCurrentAction(action, true);
1114 }
1115}
1116
1117/*!
1118 \reimp
1119*/
1120void QMenuBar::mouseReleaseEvent(QMouseEvent *e)
1121{
1122 Q_D(QMenuBar);
1123 if(e->button() != Qt::LeftButton || !d->mouseDown)
1124 return;
1125
1126 d->mouseDown = false;
1127 QAction *action = d->actionAt(e->pos());
1128 if((d->closePopupMode && action == d->currentAction) || !action || !action->menu()) {
1129 //we set the current action before activating
1130 //so that we let the leave event set the current back to 0
1131 d->setCurrentAction(action, false);
1132 if(action)
1133 d->activateAction(action, QAction::Trigger);
1134 }
1135 d->closePopupMode = 0;
1136}
1137
1138/*!
1139 \reimp
1140*/
1141void QMenuBar::keyPressEvent(QKeyEvent *e)
1142{
1143 Q_D(QMenuBar);
1144 d->updateGeometries();
1145 int key = e->key();
1146 if(isRightToLeft()) { // in reverse mode open/close key for submenues are reversed
1147 if(key == Qt::Key_Left)
1148 key = Qt::Key_Right;
1149 else if(key == Qt::Key_Right)
1150 key = Qt::Key_Left;
1151 }
1152 if(key == Qt::Key_Tab) //means right
1153 key = Qt::Key_Right;
1154 else if(key == Qt::Key_Backtab) //means left
1155 key = Qt::Key_Left;
1156
1157 bool key_consumed = false;
1158 switch(key) {
1159 case Qt::Key_Up:
1160 case Qt::Key_Down:
1161 case Qt::Key_Enter:
1162 case Qt::Key_Space:
1163 case Qt::Key_Return: {
1164 if(!style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this) || !d->currentAction)
1165 break;
1166 if(d->currentAction->menu()) {
1167 d->popupAction(d->currentAction, true);
1168 } else if(key == Qt::Key_Enter || key == Qt::Key_Return || key == Qt::Key_Space) {
1169 d->activateAction(d->currentAction, QAction::Trigger);
1170 d->setCurrentAction(d->currentAction, false);
1171 d->setKeyboardMode(false);
1172 }
1173 key_consumed = true;
1174 break; }
1175
1176 case Qt::Key_Right:
1177 case Qt::Key_Left: {
1178 if(d->currentAction) {
1179 int index = d->actions.indexOf(d->currentAction);
1180 if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) {
1181 d->setCurrentAction(nextAction, d->popupState, true);
1182 key_consumed = true;
1183 }
1184 }
1185 break; }
1186
1187 case Qt::Key_Escape:
1188 d->setCurrentAction(0);
1189 d->setKeyboardMode(false);
1190 key_consumed = true;
1191 break;
1192
1193 default:
1194 key_consumed = false;
1195 }
1196
1197 if(!key_consumed &&
1198 (!e->modifiers() ||
1199 (e->modifiers()&(Qt::MetaModifier|Qt::AltModifier))) && e->text().length()==1 && !d->popupState) {
1200 int clashCount = 0;
1201 QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;
1202 {
1203 QChar c = e->text()[0].toUpper();
1204 for(int i = 0; i < d->actions.size(); ++i) {
1205 if (d->actionRects.at(i).isNull())
1206 continue;
1207 QAction *act = d->actions.at(i);
1208 QString s = act->text();
1209 if(!s.isEmpty()) {
1210 int ampersand = s.indexOf(QLatin1Char('&'));
1211 if(ampersand >= 0) {
1212 if(s[ampersand+1].toUpper() == c) {
1213 clashCount++;
1214 if(!first)
1215 first = act;
1216 if(act == d->currentAction)
1217 currentSelected = act;
1218 else if (!firstAfterCurrent && currentSelected)
1219 firstAfterCurrent = act;
1220 }
1221 }
1222 }
1223 }
1224 }
1225 QAction *next_action = 0;
1226 if(clashCount >= 1) {
1227 if(clashCount == 1 || !d->currentAction || (currentSelected && !firstAfterCurrent))
1228 next_action = first;
1229 else
1230 next_action = firstAfterCurrent;
1231 }
1232 if(next_action) {
1233 key_consumed = true;
1234 d->setCurrentAction(next_action, true, true);
1235 }
1236 }
1237 if(key_consumed)
1238 e->accept();
1239 else
1240 e->ignore();
1241}
1242
1243/*!
1244 \reimp
1245*/
1246void QMenuBar::mouseMoveEvent(QMouseEvent *e)
1247{
1248 Q_D(QMenuBar);
1249 if (!(e->buttons() & Qt::LeftButton))
1250 d->mouseDown = false;
1251 bool popupState = d->popupState || d->mouseDown;
1252 QAction *action = d->actionAt(e->pos());
1253 if ((action && d->isVisible(action)) || !popupState)
1254 d->setCurrentAction(action, popupState);
1255}
1256
1257/*!
1258 \reimp
1259*/
1260void QMenuBar::leaveEvent(QEvent *)
1261{
1262 Q_D(QMenuBar);
1263 if((!hasFocus() && !d->popupState) ||
1264 (d->currentAction && d->currentAction->menu() == 0))
1265 d->setCurrentAction(0);
1266}
1267
1268/*!
1269 \reimp
1270*/
1271void QMenuBar::actionEvent(QActionEvent *e)
1272{
1273 Q_D(QMenuBar);
1274 d->itemsDirty = true;
1275#if defined (Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
1276 if (isNativeMenuBar()) {
1277#ifdef Q_WS_MAC
1278 QMenuBarPrivate::QMacMenuBarPrivate *nativeMenuBar = d->mac_menubar;
1279#elif defined(Q_WS_S60)
1280 QMenuBarPrivate::QSymbianMenuBarPrivate *nativeMenuBar = d->symbian_menubar;
1281#else
1282 QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar;
1283#endif
1284 if (!nativeMenuBar)
1285 return;
1286 if(e->type() == QEvent::ActionAdded)
1287 nativeMenuBar->addAction(e->action(), nativeMenuBar->findAction(e->before()));
1288 else if(e->type() == QEvent::ActionRemoved)
1289 nativeMenuBar->removeAction(e->action());
1290 else if(e->type() == QEvent::ActionChanged)
1291 nativeMenuBar->syncAction(e->action());
1292 }
1293#endif
1294
1295 if(e->type() == QEvent::ActionAdded) {
1296 connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
1297 connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
1298 } else if(e->type() == QEvent::ActionRemoved) {
1299 e->action()->disconnect(this);
1300 }
1301 if (isVisible()) {
1302 d->updateGeometries();
1303 update();
1304 }
1305}
1306
1307/*!
1308 \reimp
1309*/
1310void QMenuBar::focusInEvent(QFocusEvent *)
1311{
1312 Q_D(QMenuBar);
1313 if(d->keyboardState)
1314 d->focusFirstAction();
1315}
1316
1317/*!
1318 \reimp
1319*/
1320void QMenuBar::focusOutEvent(QFocusEvent *)
1321{
1322 Q_D(QMenuBar);
1323 if(!d->popupState) {
1324 d->setCurrentAction(0);
1325 d->setKeyboardMode(false);
1326 }
1327}
1328
1329/*!
1330 \reimp
1331 */
1332void QMenuBar::timerEvent (QTimerEvent *e)
1333{
1334 Q_D(QMenuBar);
1335 if (e->timerId() == d->autoReleaseTimer.timerId()) {
1336 d->autoReleaseTimer.stop();
1337 d->setCurrentAction(0);
1338 }
1339 QWidget::timerEvent(e);
1340}
1341
1342
1343void QMenuBarPrivate::handleReparent()
1344{
1345 Q_Q(QMenuBar);
1346 QWidget *newParent = q->parentWidget();
1347 //Note: if parent is reparented, then window may change even if parent doesn't
1348
1349 // we need to install an event filter on parent, and remove the old one
1350
1351 if (oldParent != newParent) {
1352 if (oldParent)
1353 oldParent->removeEventFilter(q);
1354 if (newParent)
1355 newParent->installEventFilter(q);
1356 }
1357
1358 //we also need event filter on top-level (for shortcuts)
1359 QWidget *newWindow = newParent ? newParent->window() : 0;
1360
1361 if (oldWindow != newWindow) {
1362 if (oldParent && oldParent != oldWindow)
1363 oldWindow->removeEventFilter(q);
1364
1365 if (newParent && newParent != newWindow)
1366 newWindow->installEventFilter(q);
1367 }
1368
1369 oldParent = newParent;
1370 oldWindow = newWindow;
1371
1372#ifdef Q_WS_MAC
1373 if (q->isNativeMenuBar() && !macWidgetHasNativeMenubar(newParent)) {
1374 // If the new parent got a native menubar from before, keep that
1375 // menubar rather than replace it with this one (because a parents
1376 // menubar has precedence over children menubars).
1377 macDestroyMenuBar();
1378 macCreateMenuBar(newParent);
1379 }
1380#endif
1381
1382#ifdef Q_WS_WINCE
1383 if (qt_wince_is_mobile() && wce_menubar)
1384 wce_menubar->rebuild();
1385#endif
1386#ifdef Q_WS_S60
1387
1388 // Construct symbian_menubar when this code path is entered first time
1389 // and when newParent != NULL
1390 if (!symbian_menubar)
1391 symbianCreateMenuBar(newParent);
1392
1393 // Reparent and rebuild menubar when parent is changed
1394 if (symbian_menubar) {
1395 if (oldParent != newParent)
1396 reparentMenuBar(oldParent, newParent);
1397 q->hide();
1398 symbian_menubar->rebuild();
1399 }
1400
1401#ifdef QT_SOFTKEYS_ENABLED
1402 // Constuct menuBarAction when this code path is entered first time
1403 if (!menuBarAction) {
1404 if (newParent) {
1405 menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, newParent);
1406 newParent->addAction(menuBarAction);
1407 }
1408 } else {
1409 // If reparenting i.e. we already have menuBarAction, remove it from old parent
1410 // and add for a new parent
1411 if (oldParent)
1412 oldParent->removeAction(menuBarAction);
1413 if (newParent)
1414 newParent->addAction(menuBarAction);
1415 }
1416#endif // QT_SOFTKEYS_ENABLED
1417#endif // Q_WS_S60
1418}
1419
1420#ifdef QT3_SUPPORT
1421/*!
1422 Sets whether the menu bar should automatically resize itself
1423 when its parent widget is resized.
1424
1425 This feature is provided to help porting to Qt 4. We recommend
1426 against using it in new code.
1427
1428 \sa autoGeometry()
1429*/
1430void QMenuBar::setAutoGeometry(bool b)
1431{
1432 Q_D(QMenuBar);
1433 d->doAutoResize = b;
1434}
1435
1436/*!
1437 Returns true if the menu bar automatically resizes itself
1438 when its parent widget is resized; otherwise returns false.
1439
1440 This feature is provided to help porting to Qt 4. We recommend
1441 against using it in new code.
1442
1443 \sa setAutoGeometry()
1444*/
1445bool QMenuBar::autoGeometry() const
1446{
1447 Q_D(const QMenuBar);
1448 return d->doAutoResize;
1449}
1450#endif
1451
1452/*!
1453 \reimp
1454*/
1455void QMenuBar::changeEvent(QEvent *e)
1456{
1457 Q_D(QMenuBar);
1458 if(e->type() == QEvent::StyleChange) {
1459 d->itemsDirty = true;
1460 setMouseTracking(style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, this));
1461 if(parentWidget())
1462 resize(parentWidget()->width(), heightForWidth(parentWidget()->width()));
1463 d->updateGeometries();
1464 } else if (e->type() == QEvent::ParentChange) {
1465 d->handleReparent();
1466 } else if (e->type() == QEvent::FontChange
1467 || e->type() == QEvent::ApplicationFontChange) {
1468 d->itemsDirty = true;
1469 d->updateGeometries();
1470#ifdef QT_SOFTKEYS_ENABLED
1471 } else if (e->type() == QEvent::LanguageChange) {
1472 if (d->menuBarAction)
1473 d->menuBarAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::MenuSoftKey));
1474#endif
1475 }
1476
1477 QWidget::changeEvent(e);
1478}
1479
1480/*!
1481 \reimp
1482*/
1483bool QMenuBar::event(QEvent *e)
1484{
1485 Q_D(QMenuBar);
1486 switch (e->type()) {
1487 case QEvent::KeyPress: {
1488 QKeyEvent *ke = (QKeyEvent*)e;
1489#if 0
1490 if(!d->keyboardState) { //all keypresses..
1491 d->setCurrentAction(0);
1492 return ;
1493 }
1494#endif
1495 if(ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
1496 keyPressEvent(ke);
1497 return true;
1498 }
1499
1500 } break;
1501#ifndef QT_NO_SHORTCUT
1502 case QEvent::Shortcut: {
1503 QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
1504 int shortcutId = se->shortcutId();
1505 for(int j = 0; j < d->shortcutIndexMap.size(); ++j) {
1506 if (shortcutId == d->shortcutIndexMap.value(j))
1507 d->_q_internalShortcutActivated(j);
1508 }
1509 } break;
1510#endif
1511 case QEvent::Show:
1512#ifdef QT3_SUPPORT
1513 if(QWidget *p = parentWidget()) {
1514 // If itemsDirty == true, updateGeometries sends the MenubarUpdated event.
1515 if (!d->itemsDirty) {
1516 QMenubarUpdatedEvent menubarUpdated(this);
1517 QApplication::sendEvent(p, &menubarUpdated);
1518 }
1519 }
1520#endif
1521 d->_q_updateLayout();
1522 break;
1523 case QEvent::ShortcutOverride: {
1524 QKeyEvent *kev = static_cast<QKeyEvent*>(e);
1525 //we only filter out escape if there is a current action
1526 if (kev->key() == Qt::Key_Escape && d->currentAction) {
1527 e->accept();
1528 return true;
1529 }
1530 }
1531 break;
1532
1533#ifdef QT3_SUPPORT
1534 case QEvent::Hide: {
1535 if(QWidget *p = parentWidget()) {
1536 QMenubarUpdatedEvent menubarUpdated(this);
1537 QApplication::sendEvent(p, &menubarUpdated);
1538 }
1539 } break;
1540#endif
1541
1542#ifndef QT_NO_WHATSTHIS
1543 case QEvent::QueryWhatsThis:
1544 e->setAccepted(d->whatsThis.size());
1545 if (QAction *action = d->actionAt(static_cast<QHelpEvent*>(e)->pos())) {
1546 if (action->whatsThis().size() || action->menu())
1547 e->accept();
1548 }
1549 return true;
1550#endif
1551 case QEvent::LayoutDirectionChange:
1552 d->_q_updateLayout();
1553 break;
1554 default:
1555 break;
1556 }
1557 return QWidget::event(e);
1558}
1559
1560/*!
1561 \reimp
1562*/
1563bool QMenuBar::eventFilter(QObject *object, QEvent *event)
1564{
1565 Q_D(QMenuBar);
1566 if (object == parent() && object) {
1567#ifdef QT3_SUPPORT
1568 if (d->doAutoResize && event->type() == QEvent::Resize) {
1569 QResizeEvent *e = (QResizeEvent *)event;
1570 int w = e->size().width();
1571 setGeometry(0, y(), w, heightForWidth(w));
1572 return false;
1573 }
1574#endif
1575 if (event->type() == QEvent::ParentChange) //GrandparentChange
1576 d->handleReparent();
1577 }
1578 if (object == d->leftWidget || object == d->rightWidget) {
1579 switch (event->type()) {
1580 case QEvent::ShowToParent:
1581 case QEvent::HideToParent:
1582 d->_q_updateLayout();
1583 break;
1584 default:
1585 break;
1586 }
1587 }
1588
1589 if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this)) {
1590 if (d->altPressed) {
1591 switch (event->type()) {
1592 case QEvent::KeyPress:
1593 case QEvent::KeyRelease:
1594 {
1595 QKeyEvent *kev = static_cast<QKeyEvent*>(event);
1596 if (kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) {
1597 if (event->type() == QEvent::KeyPress) // Alt-press does not interest us, we have the shortcut-override event
1598 break;
1599 d->setKeyboardMode(!d->keyboardState);
1600 }
1601 }
1602 // fall through
1603 case QEvent::MouseButtonPress:
1604 case QEvent::MouseButtonRelease:
1605 case QEvent::MouseMove:
1606 case QEvent::FocusIn:
1607 case QEvent::FocusOut:
1608 case QEvent::ActivationChange:
1609 d->altPressed = false;
1610 qApp->removeEventFilter(this);
1611 break;
1612 default:
1613 break;
1614 }
1615 } else if (isVisible()) {
1616 if (event->type() == QEvent::ShortcutOverride) {
1617 QKeyEvent *kev = static_cast<QKeyEvent*>(event);
1618 if ((kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta)
1619 && kev->modifiers() == Qt::AltModifier) {
1620 d->altPressed = true;
1621 qApp->installEventFilter(this);
1622 }
1623 }
1624 }
1625 }
1626
1627 return false;
1628}
1629
1630/*!
1631 Returns the QAction at \a pt. Returns 0 if there is no action at \a pt or if
1632the location has a separator.
1633
1634 \sa addAction(), addSeparator()
1635*/
1636QAction *QMenuBar::actionAt(const QPoint &pt) const
1637{
1638 Q_D(const QMenuBar);
1639 return d->actionAt(pt);
1640}
1641
1642/*!
1643 Returns the geometry of action \a act as a QRect.
1644
1645 \sa actionAt()
1646*/
1647QRect QMenuBar::actionGeometry(QAction *act) const
1648{
1649 Q_D(const QMenuBar);
1650 return d->actionRect(act);
1651}
1652
1653/*!
1654 \reimp
1655*/
1656QSize QMenuBar::minimumSizeHint() const
1657{
1658 Q_D(const QMenuBar);
1659#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
1660 const bool as_gui_menubar = !isNativeMenuBar();
1661#else
1662 const bool as_gui_menubar = true;
1663#endif
1664
1665 ensurePolished();
1666 QSize ret(0, 0);
1667 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1668 const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
1669 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
1670 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
1671 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
1672 if(as_gui_menubar) {
1673 int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
1674 d->calcActionRects(w - (2 * fw), 0);
1675 for (int i = 0; ret.isNull() && i < d->actions.count(); ++i)
1676 ret = d->actionRects.at(i).size();
1677 if (!d->extension->isHidden())
1678 ret += QSize(d->extension->sizeHint().width(), 0);
1679 ret += QSize(2*fw + hmargin, 2*fw + vmargin);
1680 }
1681 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1682 if(d->leftWidget) {
1683 QSize sz = d->leftWidget->minimumSizeHint();
1684 ret.setWidth(ret.width() + sz.width());
1685 if(sz.height() + margin > ret.height())
1686 ret.setHeight(sz.height() + margin);
1687 }
1688 if(d->rightWidget) {
1689 QSize sz = d->rightWidget->minimumSizeHint();
1690 ret.setWidth(ret.width() + sz.width());
1691 if(sz.height() + margin > ret.height())
1692 ret.setHeight(sz.height() + margin);
1693 }
1694 if(as_gui_menubar) {
1695 QStyleOptionMenuItem opt;
1696 opt.rect = rect();
1697 opt.menuRect = rect();
1698 opt.state = QStyle::State_None;
1699 opt.menuItemType = QStyleOptionMenuItem::Normal;
1700 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1701 opt.palette = palette();
1702 return (style()->sizeFromContents(QStyle::CT_MenuBar, &opt,
1703 ret.expandedTo(QApplication::globalStrut()),
1704 this));
1705 }
1706 return ret;
1707}
1708
1709/*!
1710 \reimp
1711*/
1712QSize QMenuBar::sizeHint() const
1713{
1714 Q_D(const QMenuBar);
1715#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
1716 const bool as_gui_menubar = !isNativeMenuBar();
1717#else
1718 const bool as_gui_menubar = true;
1719#endif
1720
1721
1722 ensurePolished();
1723 QSize ret(0, 0);
1724 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1725 const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
1726 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
1727 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
1728 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
1729 if(as_gui_menubar) {
1730 const int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
1731 d->calcActionRects(w - (2 * fw), 0);
1732 for (int i = 0; i < d->actionRects.count(); ++i) {
1733 const QRect &actionRect = d->actionRects.at(i);
1734 ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height()));
1735 }
1736 //the action geometries already contain the top and left
1737 //margins. So we only need to add those from right and bottom.
1738 ret += QSize(fw + hmargin, fw + vmargin);
1739 }
1740 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1741 if(d->leftWidget) {
1742 QSize sz = d->leftWidget->sizeHint();
1743 ret.setWidth(ret.width() + sz.width());
1744 if(sz.height() + margin > ret.height())
1745 ret.setHeight(sz.height() + margin);
1746 }
1747 if(d->rightWidget) {
1748 QSize sz = d->rightWidget->sizeHint();
1749 ret.setWidth(ret.width() + sz.width());
1750 if(sz.height() + margin > ret.height())
1751 ret.setHeight(sz.height() + margin);
1752 }
1753 if(as_gui_menubar) {
1754 QStyleOptionMenuItem opt;
1755 opt.rect = rect();
1756 opt.menuRect = rect();
1757 opt.state = QStyle::State_None;
1758 opt.menuItemType = QStyleOptionMenuItem::Normal;
1759 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1760 opt.palette = palette();
1761 return (style()->sizeFromContents(QStyle::CT_MenuBar, &opt,
1762 ret.expandedTo(QApplication::globalStrut()),
1763 this));
1764 }
1765 return ret;
1766}
1767
1768/*!
1769 \reimp
1770*/
1771int QMenuBar::heightForWidth(int) const
1772{
1773 Q_D(const QMenuBar);
1774#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
1775 const bool as_gui_menubar = !isNativeMenuBar();
1776#else
1777 const bool as_gui_menubar = true;
1778#endif
1779
1780 const_cast<QMenuBarPrivate*>(d)->updateGeometries();
1781 int height = 0;
1782 const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
1783 int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
1784 int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
1785 if(as_gui_menubar) {
1786 for (int i = 0; i < d->actionRects.count(); ++i)
1787 height = qMax(height, d->actionRects.at(i).height());
1788 if (height) //there is at least one non-null item
1789 height += spaceBelowMenuBar;
1790 height += 2*fw;
1791 height += 2*vmargin;
1792 }
1793 int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
1794 if(d->leftWidget)
1795 height = qMax(d->leftWidget->sizeHint().height() + margin, height);
1796 if(d->rightWidget)
1797 height = qMax(d->rightWidget->sizeHint().height() + margin, height);
1798 if(as_gui_menubar) {
1799 QStyleOptionMenuItem opt;
1800 opt.init(this);
1801 opt.menuRect = rect();
1802 opt.state = QStyle::State_None;
1803 opt.menuItemType = QStyleOptionMenuItem::Normal;
1804 opt.checkType = QStyleOptionMenuItem::NotCheckable;
1805 return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, QSize(0, height), this).height(); //not pretty..
1806 }
1807 return height;
1808}
1809
1810/*!
1811 \internal
1812*/
1813void QMenuBarPrivate::_q_internalShortcutActivated(int id)
1814{
1815 Q_Q(QMenuBar);
1816 QAction *act = actions.at(id);
1817 setCurrentAction(act, true, true);
1818 if (act && !act->menu()) {
1819 activateAction(act, QAction::Trigger);
1820 //100 is the same as the default value in QPushButton::animateClick
1821 autoReleaseTimer.start(100, q);
1822 } else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {
1823 // When we open a menu using a shortcut, we should end up in keyboard state
1824 setKeyboardMode(true);
1825 }
1826}
1827
1828void QMenuBarPrivate::_q_updateLayout()
1829{
1830 Q_Q(QMenuBar);
1831 itemsDirty = true;
1832 if (q->isVisible()) {
1833 updateGeometries();
1834 q->update();
1835 }
1836}
1837
1838/*!
1839 \fn void QMenuBar::setCornerWidget(QWidget *widget, Qt::Corner corner)
1840
1841 This sets the given \a widget to be shown directly on the left of the first
1842 menu item, or on the right of the last menu item, depending on \a corner.
1843
1844 The menu bar takes ownership of \a widget, reparenting it into the menu bar.
1845 However, if the \a corner already contains a widget, this previous widget
1846 will no longer be managed and will still be a visible child of the menu bar.
1847
1848 \note Using a corner other than Qt::TopRightCorner or Qt::TopLeftCorner
1849 will result in a warning.
1850*/
1851void QMenuBar::setCornerWidget(QWidget *w, Qt::Corner corner)
1852{
1853 Q_D(QMenuBar);
1854 switch (corner) {
1855 case Qt::TopLeftCorner:
1856 if (d->leftWidget)
1857 d->leftWidget->removeEventFilter(this);
1858 d->leftWidget = w;
1859 break;
1860 case Qt::TopRightCorner:
1861 if (d->rightWidget)
1862 d->rightWidget->removeEventFilter(this);
1863 d->rightWidget = w;
1864 break;
1865 default:
1866 qWarning("QMenuBar::setCornerWidget: Only TopLeftCorner and TopRightCorner are supported");
1867 return;
1868 }
1869
1870 if (w) {
1871 w->setParent(this);
1872 w->installEventFilter(this);
1873 }
1874
1875 d->_q_updateLayout();
1876}
1877
1878/*!
1879 Returns the widget on the left of the first or on the right of the last menu
1880 item, depending on \a corner.
1881
1882 \note Using a corner other than Qt::TopRightCorner or Qt::TopLeftCorner
1883 will result in a warning.
1884*/
1885QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const
1886{
1887 Q_D(const QMenuBar);
1888 QWidget *w = 0;
1889 switch(corner) {
1890 case Qt::TopLeftCorner:
1891 w = d->leftWidget;
1892 break;
1893 case Qt::TopRightCorner:
1894 w = d->rightWidget;
1895 break;
1896 default:
1897 qWarning("QMenuBar::cornerWidget: Only TopLeftCorner and TopRightCorner are supported");
1898 break;
1899 }
1900
1901 return w;
1902}
1903
1904/*!
1905 \property QMenuBar::nativeMenuBar
1906 \brief Whether or not a menubar will be used as a native menubar on platforms that support it
1907 \since 4.6
1908
1909 This property specifies whether or not the menubar should be used as a native menubar on platforms
1910 that support it. The currently supported platforms are Mac OS X and Windows CE. On these platforms
1911 if this property is true, the menubar is used in the native menubar and is not in the window of
1912 its parent, if false the menubar remains in the window. On other platforms the value of this
1913 attribute has no effect.
1914
1915 The default is to follow whether the Qt::AA_DontUseNativeMenuBar attribute
1916 is set for the application. Explicitly settings this property overrides
1917 the presence (or abscence) of the attribute.
1918*/
1919
1920void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
1921{
1922 Q_D(QMenuBar);
1923 if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) {
1924 d->nativeMenuBar = nativeMenuBar;
1925#ifdef Q_WS_MAC
1926 if (!d->nativeMenuBar) {
1927 extern void qt_mac_clear_menubar();
1928 qt_mac_clear_menubar();
1929 d->macDestroyMenuBar();
1930 const QList<QAction *> &menubarActions = actions();
1931 for (int i = 0; i < menubarActions.size(); ++i) {
1932 const QAction *action = menubarActions.at(i);
1933 if (QMenu *menu = action->menu()) {
1934 delete menu->d_func()->mac_menu;
1935 menu->d_func()->mac_menu = 0;
1936 }
1937 }
1938 } else {
1939 d->macCreateMenuBar(parentWidget());
1940 }
1941 macUpdateMenuBar();
1942 updateGeometry();
1943 if (!d->nativeMenuBar && parentWidget())
1944 setVisible(true);
1945#endif
1946 }
1947}
1948
1949bool QMenuBar::isNativeMenuBar() const
1950{
1951 Q_D(const QMenuBar);
1952 if (d->nativeMenuBar == -1) {
1953 return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar);
1954 }
1955 return d->nativeMenuBar;
1956}
1957
1958/*!
1959 \since 4.4
1960
1961 Sets the default action to \a act.
1962
1963 The default action is assigned to the left soft key. The menu is assigned
1964 to the right soft key.
1965
1966 Currently there is only support for the default action on Windows
1967 Mobile. On all other platforms this method is not available.
1968
1969 \sa defaultAction()
1970*/
1971
1972#ifdef Q_WS_WINCE
1973void QMenuBar::setDefaultAction(QAction *act)
1974{
1975 Q_D(QMenuBar);
1976 if (d->defaultAction == act)
1977 return;
1978#ifdef Q_WS_WINCE
1979 if (qt_wince_is_mobile())
1980 if (d->defaultAction) {
1981 disconnect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction()));
1982 disconnect(d->defaultAction, SIGNAL(destroyed()), this, SLOT(_q_updateDefaultAction()));
1983 }
1984#endif
1985 d->defaultAction = act;
1986#ifdef Q_WS_WINCE
1987 if (qt_wince_is_mobile())
1988 if (d->defaultAction) {
1989 connect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction()));
1990 connect(d->defaultAction, SIGNAL(destroyed()), this, SLOT(_q_updateDefaultAction()));
1991 }
1992 if (d->wce_menubar) {
1993 d->wce_menubar->rebuild();
1994 }
1995#endif
1996}
1997
1998/*!
1999 \since 4.4
2000
2001 Returns the current default action.
2002
2003 \sa setDefaultAction()
2004*/
2005QAction *QMenuBar::defaultAction() const
2006{
2007 return d_func()->defaultAction;
2008}
2009#endif
2010
2011/*!
2012 \fn void QMenuBar::triggered(QAction *action)
2013
2014 This signal is emitted when an action in a menu belonging to this menubar
2015 is triggered as a result of a mouse click; \a action is the action that
2016 caused the signal to be emitted.
2017
2018 Normally, you connect each menu action to a single slot using
2019 QAction::triggered(), but sometimes you will want to connect
2020 several items to a single slot (most often if the user selects
2021 from an array). This signal is useful in such cases.
2022
2023 \sa hovered(), QAction::triggered()
2024*/
2025
2026/*!
2027 \fn void QMenuBar::hovered(QAction *action)
2028
2029 This signal is emitted when a menu action is highlighted; \a action
2030 is the action that caused the event to be sent.
2031
2032 Often this is used to update status information.
2033
2034 \sa triggered(), QAction::hovered()
2035*/
2036
2037
2038#ifdef QT3_SUPPORT
2039/*!
2040 Use style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, this)
2041 instead.
2042*/
2043int QMenuBar::frameWidth() const
2044{
2045 return style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
2046}
2047
2048int QMenuBar::insertAny(const QIcon *icon, const QString *text, const QObject *receiver, const char *member,
2049 const QKeySequence *shortcut, const QMenu *popup, int id, int index)
2050{
2051 QAction *act = popup ? popup->menuAction() : new QAction(this);
2052 if(id != -1)
2053 static_cast<QMenuItem*>(act)->setId(id);
2054 if(icon)
2055 act->setIcon(*icon);
2056 if(text)
2057 act->setText(*text);
2058 if(shortcut)
2059 act->setShortcut(*shortcut);
2060 if(receiver && member)
2061 QObject::connect(act, SIGNAL(triggered(bool)), receiver, member);
2062 if(index == -1 || index >= actions().count())
2063 addAction(act);
2064 else
2065 insertAction(actions().value(index), act);
2066 return findIdForAction(act);
2067}
2068
2069/*!
2070 \since 4.2
2071
2072 Use addSeparator() or insertAction() instead.
2073
2074 \oldcode
2075 menuBar->insertSeparator();
2076 \newcode
2077 menuBar->addSeparator();
2078 \endcode
2079*/
2080int QMenuBar::insertSeparator(int index)
2081{
2082 QAction *act = new QAction(this);
2083 act->setSeparator(true);
2084 if(index == -1 || index >= actions().count())
2085 addAction(act);
2086 else
2087 insertAction(actions().value(index), act);
2088 return findIdForAction(act);
2089}
2090
2091/*!
2092 Use QAction::setData() instead.
2093*/
2094bool QMenuBar::setItemParameter(int id, int param)
2095{
2096 if(QAction *act = findActionForId(id)) {
2097 act->d_func()->param = param;
2098 return true;
2099 }
2100 return false;
2101}
2102
2103/*!
2104 Use QAction::data() instead.
2105*/
2106int QMenuBar::itemParameter(int id) const
2107{
2108 if(QAction *act = findActionForId(id))
2109 return act->d_func()->param;
2110 return id;
2111}
2112
2113QAction *QMenuBar::findActionForId(int id) const
2114{
2115 QList<QAction *> list = actions();
2116 for (int i = 0; i < list.size(); ++i) {
2117 QAction *act = list.at(i);
2118 if (findIdForAction(act) == id)
2119 return act;
2120 }
2121 return 0;
2122}
2123
2124int QMenuBar::findIdForAction(QAction *act) const
2125{
2126 Q_ASSERT(act);
2127 return act->d_func()->id;
2128}
2129#endif
2130
2131/*!
2132 \enum QMenuBar::Separator
2133
2134 \compat
2135
2136 \value Never
2137 \value InWindowsStyle
2138
2139*/
2140
2141/*!
2142 \fn void QMenuBar::addAction(QAction *action)
2143 \overload
2144
2145 Appends the action \a action to the menu bar's list of actions.
2146
2147 \sa QMenu::addAction(), QWidget::addAction(), QWidget::actions()
2148*/
2149
2150/*!
2151 \fn uint QMenuBar::count() const
2152
2153 Use actions().count() instead.
2154*/
2155
2156/*!
2157 \fn int QMenuBar::insertItem(const QString &text, const QObject *receiver, const char* member, const QKeySequence& shortcut, int id, int index)
2158
2159 Use one of the insertAction() or addAction() overloads instead.
2160*/
2161
2162/*!
2163 \fn int QMenuBar::insertItem(const QIcon& icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence& shortcut, int id, int index)
2164
2165 Use one of the insertAction() or addAction() overloads instead.
2166*/
2167
2168/*!
2169 \fn int QMenuBar::insertItem(const QPixmap &pixmap, const QObject *receiver, const char* member, const QKeySequence& shortcut, int id, int index)
2170
2171 Use one of the insertAction(), addAction(), insertMenu(), or
2172 addMenu() overloads instead.
2173*/
2174
2175/*!
2176 \fn int QMenuBar::insertItem(const QString &text, int id, int index)
2177
2178 Use one of the insertAction() or addAction() overloads instead.
2179*/
2180
2181/*!
2182 \fn int QMenuBar::insertItem(const QIcon& icon, const QString &text, int id, int index)
2183
2184 Use one of the insertAction(), addAction(), insertMenu(), or
2185 addMenu() overloads instead.
2186*/
2187
2188/*!
2189 \fn int QMenuBar::insertItem(const QString &text, QMenu *popup, int id, int index)
2190
2191 Use one of the insertMenu(), or addMenu() overloads instead.
2192*/
2193
2194/*!
2195 \fn int QMenuBar::insertItem(const QIcon& icon, const QString &text, QMenu *popup, int id, int index)
2196
2197 Use one of the insertMenu(), or addMenu() overloads instead.
2198*/
2199
2200/*!
2201 \fn int QMenuBar::insertItem(const QPixmap &pixmap, int id, int index)
2202
2203 Use one of the insertAction(), addAction(), insertMenu(), or
2204 addMenu() overloads instead.
2205*/
2206
2207/*!
2208 \fn int QMenuBar::insertItem(const QPixmap &pixmap, QMenu *popup, int id, int index)
2209
2210 Use one of the insertMenu(), or addMenu() overloads instead.
2211*/
2212
2213/*!
2214 \fn void QMenuBar::removeItem(int id)
2215
2216 Use removeAction() instead.
2217*/
2218
2219/*!
2220 \fn void QMenuBar::removeItemAt(int index)
2221
2222 Use removeAction() instead.
2223*/
2224
2225/*!
2226 \fn QKeySequence QMenuBar::accel(int id) const
2227
2228 Use shortcut() on the relevant QAction instead.
2229*/
2230
2231/*!
2232 \fn void QMenuBar::setAccel(const QKeySequence& key, int id)
2233
2234 Use setShortcut() on the relevant QAction instead.
2235*/
2236
2237/*!
2238 \fn QIcon QMenuBar::iconSet(int id) const
2239
2240 Use icon() on the relevant QAction instead.
2241*/
2242
2243/*!
2244 \fn QString QMenuBar::text(int id) const
2245
2246 Use text() on the relevant QAction instead.
2247*/
2248
2249/*!
2250 \fn QPixmap QMenuBar::pixmap(int id) const
2251
2252 Use QPixmap(icon()) on the relevant QAction instead.
2253*/
2254
2255/*!
2256 \fn void QMenuBar::setWhatsThis(int id, const QString &w)
2257
2258 Use setWhatsThis() on the relevant QAction instead.
2259*/
2260
2261/*!
2262 \fn QString QMenuBar::whatsThis(int id) const
2263
2264 Use whatsThis() on the relevant QAction instead.
2265*/
2266
2267/*!
2268 \fn void QMenuBar::changeItem(int id, const QString &text)
2269
2270 Use setText() on the relevant QAction instead.
2271*/
2272
2273/*!
2274 \fn void QMenuBar::changeItem(int id, const QPixmap &pixmap)
2275
2276 Use setText() on the relevant QAction instead.
2277*/
2278
2279/*!
2280 \fn void QMenuBar::changeItem(int id, const QIcon &icon, const QString &text)
2281
2282 Use setIcon() and setText() on the relevant QAction instead.
2283*/
2284
2285/*!
2286 \fn bool QMenuBar::isItemActive(int id) const
2287
2288 Use activeAction() instead.
2289*/
2290
2291/*!
2292 \fn bool QMenuBar::isItemEnabled(int id) const
2293
2294 Use isEnabled() on the relevant QAction instead.
2295*/
2296
2297/*!
2298 \fn void QMenuBar::setItemEnabled(int id, bool enable)
2299
2300 Use setEnabled() on the relevant QAction instead.
2301*/
2302
2303/*!
2304 \fn bool QMenuBar::isItemChecked(int id) const
2305
2306 Use isChecked() on the relevant QAction instead.
2307*/
2308
2309/*!
2310 \fn void QMenuBar::setItemChecked(int id, bool check)
2311
2312 Use setChecked() on the relevant QAction instead.
2313*/
2314
2315/*!
2316 \fn bool QMenuBar::isItemVisible(int id) const
2317
2318 Use isVisible() on the relevant QAction instead.
2319*/
2320
2321/*!
2322 \fn void QMenuBar::setItemVisible(int id, bool visible)
2323
2324 Use setVisible() on the relevant QAction instead.
2325*/
2326
2327/*!
2328 \fn int QMenuBar::indexOf(int id) const
2329
2330 Use actions().indexOf(action) on the relevant QAction instead.
2331*/
2332
2333/*!
2334 \fn int QMenuBar::idAt(int index) const
2335
2336 Use actions instead.
2337*/
2338
2339/*!
2340 \fn void QMenuBar::activateItemAt(int index)
2341
2342 Use activate() on the relevant QAction instead.
2343*/
2344
2345/*!
2346 \fn bool QMenuBar::connectItem(int id, const QObject *receiver, const char* member)
2347
2348 Use connect() on the relevant QAction instead.
2349*/
2350
2351/*!
2352 \fn bool QMenuBar::disconnectItem(int id,const QObject *receiver, const char* member)
2353
2354 Use disconnect() on the relevant QAction instead.
2355*/
2356
2357/*!
2358 \fn QMenuItem *QMenuBar::findItem(int id) const
2359
2360 Use actions instead.
2361*/
2362
2363/*!
2364 \fn Separator QMenuBar::separator() const
2365
2366 This function is provided only to make old code compile.
2367*/
2368
2369/*!
2370 \fn void QMenuBar::setSeparator(Separator sep)
2371
2372 This function is provided only to make old code compile.
2373*/
2374
2375/*!
2376 \fn QRect QMenuBar::itemRect(int index)
2377
2378 Use actionGeometry() on the relevant QAction instead.
2379*/
2380
2381/*!
2382 \fn int QMenuBar::itemAtPos(const QPoint &p)
2383
2384 There is no equivalent way to achieve this in Qt 4.
2385*/
2386
2387/*!
2388 \fn void QMenuBar::activated(int itemId);
2389
2390 Use triggered() instead.
2391*/
2392
2393/*!
2394 \fn void QMenuBar::highlighted(int itemId);
2395
2396 Use hovered() instead.
2397*/
2398
2399/*!
2400 \fn void QMenuBar::setFrameRect(QRect)
2401 \internal
2402*/
2403
2404/*!
2405 \fn QRect QMenuBar::frameRect() const
2406 \internal
2407*/
2408/*!
2409 \enum QMenuBar::DummyFrame
2410 \internal
2411
2412 \value Box
2413 \value Sunken
2414 \value Plain
2415 \value Raised
2416 \value MShadow
2417 \value NoFrame
2418 \value Panel
2419 \value StyledPanel
2420 \value HLine
2421 \value VLine
2422 \value GroupBoxPanel
2423 \value WinPanel
2424 \value ToolBarPanel
2425 \value MenuBarPanel
2426 \value PopupPanel
2427 \value LineEditPanel
2428 \value TabWidgetPanel
2429 \value MShape
2430*/
2431
2432/*!
2433 \fn void QMenuBar::setFrameShadow(DummyFrame)
2434 \internal
2435*/
2436
2437/*!
2438 \fn DummyFrame QMenuBar::frameShadow() const
2439 \internal
2440*/
2441
2442/*!
2443 \fn void QMenuBar::setFrameShape(DummyFrame)
2444 \internal
2445*/
2446
2447/*!
2448 \fn DummyFrame QMenuBar::frameShape() const
2449 \internal
2450*/
2451
2452/*!
2453 \fn void QMenuBar::setFrameStyle(int)
2454 \internal
2455*/
2456
2457/*!
2458 \fn int QMenuBar::frameStyle() const
2459 \internal
2460*/
2461
2462/*!
2463 \fn void QMenuBar::setLineWidth(int)
2464 \internal
2465*/
2466
2467/*!
2468 \fn int QMenuBar::lineWidth() const
2469 \internal
2470*/
2471
2472/*!
2473 \fn void QMenuBar::setMargin(int margin)
2474 Sets the width of the margin around the contents of the widget to \a margin.
2475
2476 Use QWidget::setContentsMargins() instead.
2477 \sa margin(), QWidget::setContentsMargins()
2478*/
2479
2480/*!
2481 \fn int QMenuBar::margin() const
2482 Returns the width of the margin around the contents of the widget.
2483
2484 Use QWidget::getContentsMargins() instead.
2485 \sa setMargin(), QWidget::getContentsMargins()
2486*/
2487
2488/*!
2489 \fn void QMenuBar::setMidLineWidth(int)
2490 \internal
2491*/
2492
2493/*!
2494 \fn int QMenuBar::midLineWidth() const
2495 \internal
2496*/
2497
2498// for private slots
2499
2500
2501QT_END_NAMESPACE
2502
2503#include <moc_qmenubar.cpp>
2504
2505#endif // QT_NO_MENUBAR
Note: See TracBrowser for help on using the repository browser.