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

Last change on this file since 769 was 769, checked in by Dmitry A. Kuminov, 15 years ago

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

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