Qt 4.8
qmenu_mac.mm
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qmenu.h"
43 #include "qhash.h"
44 #include <qdebug.h>
45 #include "qapplication.h"
46 #include <private/qt_mac_p.h>
47 #include "qregexp.h"
48 #include "qmainwindow.h"
49 #include "qdockwidget.h"
50 #include "qtoolbar.h"
51 #include "qevent.h"
52 #include "qstyle.h"
53 #include "qwidgetaction.h"
54 #include "qmacnativewidget_mac.h"
55 
56 #include <private/qapplication_p.h>
57 #include <private/qcocoaapplication_mac_p.h>
58 #include <private/qmenu_p.h>
59 #include <private/qmenubar_p.h>
60 #include <private/qcocoamenuloader_mac_p.h>
61 #include <private/qcocoamenu_mac_p.h>
62 #include <private/qt_cocoa_helpers_mac_p.h>
63 #include <Cocoa/Cocoa.h>
64 
66 
67 /*****************************************************************************
68  QMenu debug facilities
69  *****************************************************************************/
70 
71 /*****************************************************************************
72  QMenu globals
73  *****************************************************************************/
77 
79 
80 #ifndef QT_MAC_USE_COCOA
82 const UInt32 kMenuCreatorQt = 'cute';
83 enum {
91 
94 };
95 #endif
96 
97 static struct {
99  bool modal;
100 } qt_mac_current_menubar = { 0, false };
101 
102 
103 
104 
105 /*****************************************************************************
106  Externals
107  *****************************************************************************/
108 extern OSViewRef qt_mac_hiview_for(const QWidget *w); //qwidget_mac.cpp
109 extern HIViewRef qt_mac_hiview_for(OSWindowRef w); //qwidget_mac.cpp
110 extern IconRef qt_mac_create_iconref(const QPixmap &px); //qpixmap_mac.cpp
111 extern QWidget * mac_keyboard_grabber; //qwidget_mac.cpp
112 extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication_xxx.cpp
113 RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
114 void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
115 
116 /*****************************************************************************
117  QMenu utility functions
118  *****************************************************************************/
120 {
121  return menu && menu->receivers(SIGNAL(aboutToShow()));
122 }
123 
125 {
126  if (menu) {
127 #ifndef QT_MAC_USE_COCOA
128  int ret = 0;
129  const int items = CountMenuItems(menu);
130  for(int i = 0; i < items; i++) {
131  MenuItemAttributes attr;
132  if (GetMenuItemAttributes(menu, i+1, &attr) == noErr &&
133  attr & kMenuItemAttrHidden)
134  continue;
135  ++ret;
136  }
137  return ret;
138 #else
139  return [menu numberOfItems];
140 #endif
141  }
142  return 0;
143 }
144 
146 {
147  quint32 ret = 0;
148  const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
149 #ifndef QT_MAC_USE_COCOA
150  if ((accel_key & Qt::ALT) == Qt::ALT)
151  ret |= kMenuOptionModifier;
152  if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
153  ret |= kMenuShiftModifier;
154  if (dontSwap) {
155  if ((accel_key & Qt::META) != Qt::META)
156  ret |= kMenuNoCommandModifier;
157  if ((accel_key & Qt::CTRL) == Qt::CTRL)
158  ret |= kMenuControlModifier;
159  } else {
160  if ((accel_key & Qt::CTRL) != Qt::CTRL)
161  ret |= kMenuNoCommandModifier;
162  if ((accel_key & Qt::META) == Qt::META)
163  ret |= kMenuControlModifier;
164  }
165 #else
166  if ((accel_key & Qt::CTRL) == Qt::CTRL)
167  ret |= (dontSwap ? NSControlKeyMask : NSCommandKeyMask);
168  if ((accel_key & Qt::META) == Qt::META)
169  ret |= (dontSwap ? NSCommandKeyMask : NSControlKeyMask);
170  if ((accel_key & Qt::ALT) == Qt::ALT)
171  ret |= NSAlternateKeyMask;
172  if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
173  ret |= NSShiftKeyMask;
174 #endif
175  return ret;
176 }
177 
179 {
180 #ifdef QT_MAC_USE_COCOA
182  NSMenu *mainMenu = [NSApp mainMenu];
183  [mainMenu cancelTracking];
184  for (NSMenuItem *item in [mainMenu itemArray]) {
185  if ([item submenu]) {
186  [[item submenu] cancelTracking];
187  }
188  }
189 #else
190  CancelMenuTracking(AcquireRootMenu(), true, 0);
191 #endif
192 }
193 
195  const QMacMenuAction *action)
196 {
197  bool visible = action->action->isVisible();
198  if (visible && action->action->text() == QString(QChar(0x14)))
199  return false;
200  if (visible && action->action->menu() && !action->action->menu()->actions().isEmpty() &&
201  !qt_mac_CountMenuItems(action->action->menu()->macMenu(mbp->apple_menu)) &&
202  !qt_mac_watchingAboutToShow(action->action->menu())) {
203  return false;
204  }
205  return visible;
206 }
207 
208 #ifndef QT_MAC_USE_COCOA
209 bool qt_mac_activate_action(MenuRef menu, uint command, QAction::ActionEvent action_e, bool by_accel)
210 {
211  //fire event
212  QMacMenuAction *action = 0;
213  if (GetMenuCommandProperty(menu, command, kMenuCreatorQt, kMenuPropertyQAction, sizeof(action), 0, &action) != noErr) {
214  QMenuMergeList *list = 0;
215  GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
216  sizeof(list), 0, &list);
217  if (!list && qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
218  MenuRef apple_menu = qt_mac_current_menubar.qmenubar->d_func()->mac_menubar->apple_menu;
219  GetMenuItemProperty(apple_menu, 0, kMenuCreatorQt, kMenuPropertyMergeList, sizeof(list), 0, &list);
220  if (list)
221  menu = apple_menu;
222  }
223  if (list) {
224  for(int i = 0; i < list->size(); ++i) {
225  QMenuMergeItem item = list->at(i);
226  if (item.command == command && item.action) {
227  action = item.action;
228  break;
229  }
230  }
231  }
232  if (!action)
233  return false;
234  }
235 
236  if (action_e == QAction::Trigger && by_accel && action->ignore_accel) //no, not a real accel (ie tab)
237  return false;
238 
239  // Unhighlight the highlighted menu item before triggering the action to
240  // prevent items from staying highlighted while a modal dialog is shown.
241  // This also fixed the problem that parentless modal dialogs leave
242  // the menu item highlighted (since the menu bar is cleared for these types of dialogs).
243  if (action_e == QAction::Trigger)
244  HiliteMenu(0);
245 
246  action->action->activate(action_e);
247 
248  //now walk up firing for each "caused" widget (like in the platform independent menu)
249  QWidget *caused = 0;
250  if (action_e == QAction::Hover && GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), 0, &caused) == noErr) {
251  MenuRef caused_menu = 0;
252  if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused))
253  caused_menu = qmenu2->macMenu();
254  else if (QMenuBar *qmenubar2 = qobject_cast<QMenuBar*>(caused))
255  caused_menu = qmenubar2->macMenu();
256  else
257  caused_menu = 0;
258  while(caused_menu) {
259  //fire
260  QWidget *widget = 0;
261  GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(widget), 0, &widget);
262  if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
263  action->action->showStatusText(widget);
264  emit qmenu->hovered(action->action);
265  } else if (QMenuBar *qmenubar = qobject_cast<QMenuBar*>(widget)) {
266  action->action->showStatusText(widget);
267  emit qmenubar->hovered(action->action);
268  break; //nothing more..
269  }
270 
271  //walk up
272  if (GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget,
273  sizeof(caused), 0, &caused) != noErr)
274  break;
275  if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused))
276  caused_menu = qmenu2->macMenu();
277  else if (QMenuBar *qmenubar2 = qobject_cast<QMenuBar*>(caused))
278  caused_menu = qmenubar2->macMenu();
279  else
280  caused_menu = 0;
281  }
282  }
283  return true;
284 }
285 
286 //lookup a QMacMenuAction in a menu
287 static int qt_mac_menu_find_action(MenuRef menu, MenuCommand cmd)
288 {
289  MenuItemIndex ret_idx;
290  MenuRef ret_menu;
291  if (GetIndMenuItemWithCommandID(menu, cmd, 1, &ret_menu, &ret_idx) == noErr) {
292  if (ret_menu == menu)
293  return (int)ret_idx;
294  }
295  return -1;
296 }
298 {
299  return qt_mac_menu_find_action(menu, action->command);
300 }
301 
303 Q_GLOBAL_STATIC(EventHandlerHash, menu_eventHandlers_hash)
304 
305 static EventTypeSpec widget_in_menu_events[] = {
306  { kEventClassMenu, kEventMenuMeasureItemWidth },
307  { kEventClassMenu, kEventMenuMeasureItemHeight },
308  { kEventClassMenu, kEventMenuDrawItem },
309  { kEventClassMenu, kEventMenuCalculateSize }
310 };
311 
313 {
314  UInt32 ekind = GetEventKind(event);
315  UInt32 eclass = GetEventClass(event);
316  OSStatus result = eventNotHandledErr;
317  switch (eclass) {
318  case kEventClassMenu:
319  switch (ekind) {
320  default:
321  break;
322  case kEventMenuMeasureItemWidth: {
323  MenuItemIndex item;
324  GetEventParameter(event, kEventParamMenuItemIndex, typeMenuItemIndex,
325  0, sizeof(item), 0, &item);
326  OSMenuRef menu;
327  GetEventParameter(event, kEventParamDirectObject, typeMenuRef, 0, sizeof(menu), 0, &menu);
328  QWidget *widget;
329  if (GetMenuItemProperty(menu, item, kMenuCreatorQt, kMenuPropertyWidgetActionWidget,
330  sizeof(widget), 0, &widget) == noErr) {
331  short width = short(widget->sizeHint().width());
332  SetEventParameter(event, kEventParamMenuItemWidth, typeSInt16,
333  sizeof(short), &width);
334  result = noErr;
335  }
336  break; }
337  case kEventMenuMeasureItemHeight: {
338  MenuItemIndex item;
339  GetEventParameter(event, kEventParamMenuItemIndex, typeMenuItemIndex,
340  0, sizeof(item), 0, &item);
341  OSMenuRef menu;
342  GetEventParameter(event, kEventParamDirectObject, typeMenuRef, 0, sizeof(menu), 0, &menu);
343  QWidget *widget;
344  if (GetMenuItemProperty(menu, item, kMenuCreatorQt, kMenuPropertyWidgetActionWidget,
345  sizeof(widget), 0, &widget) == noErr && widget) {
346  short height = short(widget->sizeHint().height());
347  SetEventParameter(event, kEventParamMenuItemHeight, typeSInt16,
348  sizeof(short), &height);
349  result = noErr;
350  }
351  break; }
352  case kEventMenuDrawItem:
353  result = noErr;
354  break;
355  case kEventMenuCalculateSize: {
356  result = CallNextEventHandler(er, event);
357  if (result == noErr) {
358  OSMenuRef menu;
359  GetEventParameter(event, kEventParamDirectObject, typeMenuRef, 0, sizeof(menu), 0, &menu);
360  HIViewRef content;
361  HIMenuGetContentView(menu, kThemeMenuTypePullDown, &content);
362  UInt16 count = CountMenuItems(menu);
363  for (MenuItemIndex i = 1; i <= count; ++i) {
364  QWidget *widget;
365  if (GetMenuItemProperty(menu, i, kMenuCreatorQt, kMenuPropertyWidgetActionWidget,
366  sizeof(widget), 0, &widget) == noErr && widget) {
367  RgnHandle itemRgn = qt_mac_get_rgn();
368  GetControlRegion(content, i, itemRgn);
369 
370  Rect bounds;
371  GetRegionBounds( itemRgn, &bounds );
372  qt_mac_dispose_rgn(itemRgn);
373  widget->setGeometry(bounds.left, bounds.top,
374  bounds.right - bounds.left, bounds.bottom - bounds.top);
375  }
376  }
377  }
378  break; }
379  }
380  }
381  return result;
382 }
383 
384 //handling of events for menurefs created by Qt..
385 static EventTypeSpec menu_events[] = {
386  { kEventClassCommand, kEventCommandProcess },
387  { kEventClassMenu, kEventMenuTargetItem },
388  { kEventClassMenu, kEventMenuOpening },
389  { kEventClassMenu, kEventMenuClosed }
390 };
391 
392 // Special case for kEventMenuMatchKey, see qt_mac_create_menu below.
393 static EventTypeSpec menu_menu_events[] = {
394  { kEventClassMenu, kEventMenuMatchKey }
395 };
396 
398 {
399  QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData);
400 
401  bool handled_event = true;
402  UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
403  switch(eclass) {
404  case kEventClassCommand:
405  if (ekind == kEventCommandProcess) {
406  UInt32 context;
407  GetEventParameter(event, kEventParamMenuContext, typeUInt32,
408  0, sizeof(context), 0, &context);
409  HICommand cmd;
410  GetEventParameter(event, kEventParamDirectObject, typeHICommand,
411  0, sizeof(cmd), 0, &cmd);
412  if (!mac_keyboard_grabber && (context & kMenuContextKeyMatching)) {
413  QMacMenuAction *action = 0;
414  if (GetMenuCommandProperty(cmd.menu.menuRef, cmd.commandID, kMenuCreatorQt,
415  kMenuPropertyQAction, sizeof(action), 0, &action) == noErr) {
416  QWidget *widget = 0;
417  if (qApp->activePopupWidget())
418  widget = (qApp->activePopupWidget()->focusWidget() ?
419  qApp->activePopupWidget()->focusWidget() : qApp->activePopupWidget());
422  if (widget) {
423  int key = action->action->shortcut();
425  Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask));
426  accel_ev.ignore();
427  qt_sendSpontaneousEvent(widget, &accel_ev);
428  if (accel_ev.isAccepted()) {
429  handled_event = false;
430  break;
431  }
432  }
433  }
434  }
435  handled_event = qt_mac_activate_action(cmd.menu.menuRef, cmd.commandID,
436  QAction::Trigger, context & kMenuContextKeyMatching);
437  }
438  break;
439  case kEventClassMenu: {
440  MenuRef menu;
441  GetEventParameter(event, kEventParamDirectObject, typeMenuRef, NULL, sizeof(menu), NULL, &menu);
442  if (ekind == kEventMenuMatchKey) {
443  // Don't activate any actions if we are showing a native modal dialog,
444  // the key events should go to the dialog in this case.
446  return menuItemNotFoundErr;
447 
448  handled_event = false;
449  } else if (ekind == kEventMenuTargetItem) {
450  MenuCommand command;
451  GetEventParameter(event, kEventParamMenuCommand, typeMenuCommand,
452  0, sizeof(command), 0, &command);
453  handled_event = qt_mac_activate_action(menu, command, QAction::Hover, false);
454  } else if (ekind == kEventMenuOpening || ekind == kEventMenuClosed) {
455  qt_mac_menus_open_count += (ekind == kEventMenuOpening) ? 1 : -1;
456  MenuRef mr;
457  GetEventParameter(event, kEventParamDirectObject, typeMenuRef,
458  0, sizeof(mr), 0, &mr);
459 
460  QWidget *widget = 0;
461  if (GetMenuItemProperty(mr, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(widget), 0, &widget) == noErr) {
462  if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
463  handled_event = true;
464  if (ekind == kEventMenuOpening) {
465  emit qmenu->aboutToShow();
466 
467  int merged = 0;
468  const QMenuPrivate::QMacMenuPrivate *mac_menu = qmenu->d_func()->mac_menu;
469  const int ActionItemsCount = mac_menu->actionItems.size();
470  for(int i = 0; i < ActionItemsCount; ++i) {
471  QMacMenuAction *action = mac_menu->actionItems.at(i);
472  if (action->action->isSeparator()) {
473  bool hide = false;
474  if(!action->action->isVisible()) {
475  hide = true;
476  } else if (merged && merged == i) {
477  hide = true;
478  } else {
479  for(int l = i+1; l < mac_menu->actionItems.size(); ++l) {
480  QMacMenuAction *action = mac_menu->actionItems.at(l);
481  if (action->merged) {
482  hide = true;
483  } else if (action->action->isSeparator()) {
484  if (hide)
485  break;
486  } else if (!action->merged) {
487  hide = false;
488  break;
489  }
490  }
491  }
492 
493  const int index = qt_mac_menu_find_action(mr, action);
494  if (hide) {
495  ++merged;
496  ChangeMenuItemAttributes(mr, index, kMenuItemAttrHidden, 0);
497  } else {
498  ChangeMenuItemAttributes(mr, index, 0, kMenuItemAttrHidden);
499  }
500  } else if (action->merged) {
501  ++merged;
502  }
503  }
504  } else {
505  emit qmenu->aboutToHide();
506  }
507  }
508  }
509  } else {
510  handled_event = false;
511  }
512  break; }
513  default:
514  handled_event = false;
515  break;
516  }
517  if (!handled_event) //let the event go through
518  return CallNextEventHandler(er, event);
519  return noErr; //we eat the event
520 }
521 static EventHandlerRef mac_menu_event_handler = 0;
522 static EventHandlerUPP mac_menu_eventUPP = 0;
524 {
526  RemoveEventHandler(mac_menu_event_handler);
528  }
529  if (mac_menu_eventUPP) {
530  DisposeEventHandlerUPP(mac_menu_eventUPP);
531  mac_menu_eventUPP = 0;
532  }
533 }
535 {
536  if (!mac_menu_event_handler) {
537  mac_menu_eventUPP = NewEventHandlerUPP(qt_mac_menu_event);
538  InstallEventHandler(GetApplicationEventTarget(), mac_menu_eventUPP,
539  GetEventTypeCount(menu_events), menu_events, 0,
542  }
543 }
544 
545 
546 //enabling of commands
547 static void qt_mac_command_set_enabled(MenuRef menu, UInt32 cmd, bool b)
548 {
549  if (cmd == kHICommandQuit)
551 
552  if (b) {
553  EnableMenuCommand(menu, cmd);
554  if (MenuRef dock_menu = GetApplicationDockTileMenu())
555  EnableMenuCommand(dock_menu, cmd);
556  } else {
557  DisableMenuCommand(menu, cmd);
558  if (MenuRef dock_menu = GetApplicationDockTileMenu())
559  DisableMenuCommand(dock_menu, cmd);
560  }
561 }
562 
563 static bool qt_mac_auto_apple_menu(MenuCommand cmd)
564 {
565  return (cmd == kHICommandPreferences || cmd == kHICommandQuit);
566 }
567 
568 static void qt_mac_get_accel(quint32 accel_key, quint32 *modif, quint32 *key) {
569  if (modif) {
570  *modif = constructModifierMask(accel_key);
571  }
572 
573  accel_key &= ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL);
574  if (key) {
575  *key = 0;
576  if (accel_key == Qt::Key_Return)
577  *key = kMenuReturnGlyph;
578  else if (accel_key == Qt::Key_Enter)
579  *key = kMenuEnterGlyph;
580  else if (accel_key == Qt::Key_Tab)
581  *key = kMenuTabRightGlyph;
582  else if (accel_key == Qt::Key_Backspace)
583  *key = kMenuDeleteLeftGlyph;
584  else if (accel_key == Qt::Key_Delete)
585  *key = kMenuDeleteRightGlyph;
586  else if (accel_key == Qt::Key_Escape)
587  *key = kMenuEscapeGlyph;
588  else if (accel_key == Qt::Key_PageUp)
589  *key = kMenuPageUpGlyph;
590  else if (accel_key == Qt::Key_PageDown)
591  *key = kMenuPageDownGlyph;
592  else if (accel_key == Qt::Key_Up)
593  *key = kMenuUpArrowGlyph;
594  else if (accel_key == Qt::Key_Down)
595  *key = kMenuDownArrowGlyph;
596  else if (accel_key == Qt::Key_Left)
597  *key = kMenuLeftArrowGlyph;
598  else if (accel_key == Qt::Key_Right)
599  *key = kMenuRightArrowGlyph;
600  else if (accel_key == Qt::Key_CapsLock)
601  *key = kMenuCapsLockGlyph;
602  else if (accel_key >= Qt::Key_F1 && accel_key <= Qt::Key_F15)
603  *key = (accel_key - Qt::Key_F1) + kMenuF1Glyph;
604  else if (accel_key == Qt::Key_Home)
605  *key = kMenuNorthwestArrowGlyph;
606  else if (accel_key == Qt::Key_End)
607  *key = kMenuSoutheastArrowGlyph;
608  }
609 }
610 #else // Cocoa
611 static inline void syncNSMenuItemVisiblity(NSMenuItem *menuItem, bool actionVisibility)
612 {
613  [menuItem setHidden:NO];
614  [menuItem setHidden:YES];
615  [menuItem setHidden:!actionVisibility];
616 }
617 
618 static inline void syncNSMenuItemEnabled(NSMenuItem *menuItem, bool enabled)
619 {
620  [menuItem setEnabled:NO];
621  [menuItem setEnabled:YES];
622  [menuItem setEnabled:enabled];
623 }
624 
625 static inline void syncMenuBarItemsVisiblity(const QMenuBarPrivate::QMacMenuBarPrivate *mac_menubar)
626 {
627  const QList<QMacMenuAction *> &menubarActions = mac_menubar->actionItems;
628  for (int i = 0; i < menubarActions.size(); ++i) {
629  const QMacMenuAction *action = menubarActions.at(i);
630  syncNSMenuItemVisiblity(action->menuItem, actualMenuItemVisibility(mac_menubar, action));
631  }
632 }
633 
634 static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
635 {
636  return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
637 }
638 
639 static NSMenuItem *createNSMenuItem(const QString &title)
640 {
641  NSMenuItem *item = [[NSMenuItem alloc]
642  initWithTitle:qt_mac_QStringToNSString(title)
643  action:@selector(qtDispatcherToQAction:) keyEquivalent:@""];
644  [item setTarget:nil];
645  return item;
646 }
647 #endif
648 
649 
650 
651 // helper that recurses into a menu structure and en/dis-ables them
653 {
654 #ifndef QT_MAC_USE_COCOA
655  for (int i = 0; i < CountMenuItems(menu); i++) {
656  OSMenuRef submenu;
657  GetMenuItemHierarchicalMenu(menu, i+1, &submenu);
658  if (submenu != merge) {
659  if (submenu)
660  qt_mac_set_modal_state_helper_recursive(submenu, merge, on);
661  if (on)
662  DisableMenuItem(submenu, 0);
663  else
664  EnableMenuItem(submenu, 0);
665  }
666  }
667 #else
668  bool modalWindowOnScreen = qApp->activeModalWidget() != 0;
669  for (NSMenuItem *item in [menu itemArray]) {
670  OSMenuRef submenu = [item submenu];
671  if (submenu != merge) {
672  if (submenu)
673  qt_mac_set_modal_state_helper_recursive(submenu, merge, on);
674  if (!on) {
675  // The item should follow what the QAction has.
676  if ([item tag]) {
677  QAction *action = reinterpret_cast<QAction *>([item tag]);
678  syncNSMenuItemEnabled(item, action->isEnabled());
679  } else {
680  syncNSMenuItemEnabled(item, YES);
681  }
682  // We sneak in some extra code here to handle a menu problem:
683  // If there is no window on screen, we cannot set 'nil' as
684  // menu item target, because then cocoa will disable the item
685  // (guess it assumes that there will be no first responder to
686  // catch the trigger anyway?) OTOH, If we have a modal window,
687  // then setting the menu loader as target will make cocoa not
688  // deliver the trigger because the loader is then seen as modally
689  // shaddowed). So either way there are shortcomings. Instead, we
690  // decide the target as late as possible:
691  [item setTarget:modalWindowOnScreen ? nil : getMenuLoader()];
692  } else {
693  syncNSMenuItemEnabled(item, NO);
694  }
695  }
696  }
697 #endif
698 }
699 
700 //toggling of modal state
701 static void qt_mac_set_modal_state(OSMenuRef menu, bool on)
702 {
703 #ifndef QT_MAC_USE_COCOA
704  OSMenuRef merge = 0;
705  GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu,
706  sizeof(merge), 0, &merge);
707 
709 
710  UInt32 commands[] = { kHICommandQuit, kHICommandPreferences, kHICommandAbout, kHICommandAboutQt, 0 };
711  for(int c = 0; commands[c]; c++) {
712  bool enabled = !on;
713  if (enabled) {
714  QMacMenuAction *action = 0;
715  GetMenuCommandProperty(menu, commands[c], kMenuCreatorQt, kMenuPropertyQAction,
716  sizeof(action), 0, &action);
717  if (!action && merge) {
718  GetMenuCommandProperty(merge, commands[c], kMenuCreatorQt, kMenuPropertyQAction,
719  sizeof(action), 0, &action);
720  if (!action) {
721  QMenuMergeList *list = 0;
722  GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
723  sizeof(list), 0, &list);
724  for(int i = 0; list && i < list->size(); ++i) {
725  QMenuMergeItem item = list->at(i);
726  if (item.command == commands[c] && item.action) {
727  action = item.action;
728  break;
729  }
730  }
731  }
732  }
733 
734  if (!action) {
735  if (commands[c] != kHICommandQuit)
736  enabled = false;
737  } else {
738  enabled = action->action ? action->action->isEnabled() : 0;
739  }
740  }
741  qt_mac_command_set_enabled(menu, commands[c], enabled);
742  }
743 #else
746  // I'm ignoring the special items now, since they should get handled via a syncAction()
747 #endif
748 }
749 
751 {
752  return qt_mac_menus_open_count > 0;
753 }
754 
756 {
757 #ifdef QT_MAC_USE_COCOA
758  [menu release];
759  // Update the menu item if this action still owns it. For some items
760  // (like 'Quit') ownership will be transferred between all menu bars...
761  if (action && action.data() == reinterpret_cast<QAction *>([menuItem tag])) {
763  // Check if the item is owned by Qt, and should be hidden to keep it from causing
764  // problems. Do it for everything but the quit menu item since that should always
765  // be visible.
767  [menuItem setHidden:YES];
768  } else if (role == QAction::TextHeuristicRole
769  && menuItem != [getMenuLoader() quitMenuItem]) {
770  [menuItem setHidden:YES];
771  }
772  [menuItem setTag:nil];
773  }
774  [menuItem release];
775 #endif
776 }
777 
778 #ifndef QT_MAC_USE_COCOA
780 #else
782 #endif
783 {
784  if (qt_mac_no_menubar_merge || action->action->menu() || action->action->isSeparator()
785  || action->action->menuRole() == QAction::NoRole)
786  return 0;
787 
789  int st = t.lastIndexOf(QLatin1Char('\t'));
790  if (st != -1)
791  t.remove(st, t.length()-st);
792  t.replace(QRegExp(QString::fromLatin1("\\.*$")), QLatin1String("")); //no ellipses
793  //now the fun part
794 #ifndef QT_MAC_USE_COCOA
795  MenuCommand ret = 0;
796 #else
797  NSMenuItem *ret = 0;
798  QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
799 #endif
800  switch (action->action->menuRole()) {
801  case QAction::NoRole:
802  ret = 0;
803  break;
805 #ifndef QT_MAC_USE_COCOA
806  {
807  QMenuMergeList *list = 0;
808  if (GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
809  sizeof(list), 0, &list) == noErr && list) {
810  MenuCommand lastCustom = kHICommandCustomMerge;
811  for(int i = 0; i < list->size(); ++i) {
812  QMenuMergeItem item = list->at(i);
813  if (item.command == lastCustom)
814  ++lastCustom;
815  }
816  ret = lastCustom;
817  } else {
818  // The list hasn't been created, so, must be the first one.
819  ret = kHICommandCustomMerge;
820  }
821  }
822 #else
823  ret = [loader appSpecificMenuItem];
824 #endif
825  break;
826  case QAction::AboutRole:
827 #ifndef QT_MAC_USE_COCOA
828  ret = kHICommandAbout;
829 #else
830  ret = [loader aboutMenuItem];
831 #endif
832  break;
834 #ifndef QT_MAC_USE_COCOA
835  ret = kHICommandAboutQt;
836 #else
837  ret = [loader aboutQtMenuItem];
838 #endif
839  break;
840  case QAction::QuitRole:
841 #ifndef QT_MAC_USE_COCOA
842  ret = kHICommandQuit;
843 #else
844  ret = [loader quitMenuItem];
845 #endif
846  break;
848 #ifndef QT_MAC_USE_COCOA
849  ret = kHICommandPreferences;
850 #else
851  ret = [loader preferencesMenuItem];
852 #endif
853  break;
855  QString aboutString = QMenuBar::tr("About").toLower();
856  if (t.startsWith(aboutString) || t.endsWith(aboutString)) {
857  if (t.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1) {
858 #ifndef QT_MAC_USE_COCOA
859  ret = kHICommandAbout;
860 #else
861  ret = [loader aboutMenuItem];
862 #endif
863  } else {
864 #ifndef QT_MAC_USE_COCOA
865  ret = kHICommandAboutQt;
866 #else
867  ret = [loader aboutQtMenuItem];
868 #endif
869  }
870  } else if (t.startsWith(QMenuBar::tr("Config").toLower())
871  || t.startsWith(QMenuBar::tr("Preference").toLower())
872  || t.startsWith(QMenuBar::tr("Options").toLower())
873  || t.startsWith(QMenuBar::tr("Setting").toLower())
874  || t.startsWith(QMenuBar::tr("Setup").toLower())) {
875 #ifndef QT_MAC_USE_COCOA
876  ret = kHICommandPreferences;
877 #else
878  ret = [loader preferencesMenuItem];
879 #endif
880  } else if (t.startsWith(QMenuBar::tr("Quit").toLower())
881  || t.startsWith(QMenuBar::tr("Exit").toLower())) {
882 #ifndef QT_MAC_USE_COCOA
883  ret = kHICommandQuit;
884 #else
885  ret = [loader quitMenuItem];
886 #endif
887  }
888  }
889  break;
890  }
891 
892 #ifndef QT_MAC_USE_COCOA
893  QMenuMergeList *list = 0;
894  if (GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
895  sizeof(list), 0, &list) == noErr && list) {
896  for(int i = 0; i < list->size(); ++i) {
897  QMenuMergeItem item = list->at(i);
898  if (item.command == ret && item.action)
899  return 0;
900  }
901  }
902 
903  QAction *cmd_action = 0;
904  if (GetMenuCommandProperty(merge, ret, kMenuCreatorQt, kMenuPropertyQAction,
905  sizeof(cmd_action), 0, &cmd_action) == noErr && cmd_action)
906  return 0; //already taken
907 #else
908  if (QMenuMergeList *list = QMenuPrivate::mergeMenuItemsHash.value(merge)) {
909  for(int i = 0; i < list->size(); ++i) {
910  const QMenuMergeItem &item = list->at(i);
911  if (item.menuItem == ret && item.action)
912  return 0;
913  }
914  }
915 
916 #endif
917  return ret;
918 }
919 
921 {
922  QString ret;
924 #ifdef QT_MAC_USE_COCOA
925  QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
926 #endif
928  ret = action->action->text();
929 #ifndef QT_MAC_USE_COCOA
930  else if (action->command == kHICommandAbout)
932  else if (action->command == kHICommandAboutQt)
933  ret = QMenuBar::tr("About Qt");
934  else if (action->command == kHICommandPreferences)
936  else if (action->command == kHICommandQuit)
938 #else
939  else if (action->menuItem == [loader aboutMenuItem]) {
941  } else if (action->menuItem == [loader aboutQtMenuItem]) {
942  if (action->action->text() == QString("About Qt"))
943  ret = QMenuBar::tr("About Qt");
944  else
945  ret = action->action->text();
946  } else if (action->menuItem == [loader preferencesMenuItem]) {
948  } else if (action->menuItem == [loader quitMenuItem]) {
950  }
951 #endif
952  return ret;
953 }
954 
956 {
957  QKeySequence ret;
958 #ifdef QT_MAC_USE_COCOA
959  QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
960 #endif
962  ret = action->action->shortcut();
963 #ifndef QT_MAC_USE_COCOA
964  else if (action->command == kHICommandPreferences)
966  else if (action->command == kHICommandQuit)
968 #else
969  else if (action->menuItem == [loader preferencesMenuItem])
971  else if (action->menuItem == [loader quitMenuItem])
973 #endif
974  return ret;
975 }
976 
982 
983 /*****************************************************************************
984  QMenu bindings
985  *****************************************************************************/
987 {
988 }
989 
991 {
992 #ifndef QT_MAC_USE_COCOA
994  QMacMenuAction *action = (*it);
995  RemoveMenuCommandProperty(action->menu, action->command, kMenuCreatorQt, kMenuPropertyQAction);
996  if (action->merged) {
997  QMenuMergeList *list = 0;
998  GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
999  sizeof(list), 0, &list);
1000  for(int i = 0; list && i < list->size(); ) {
1001  QMenuMergeItem item = list->at(i);
1002  if (item.action == action)
1003  list->removeAt(i);
1004  else
1005  ++i;
1006  }
1007  }
1008  delete action;
1009  }
1010  if (menu) {
1011  EventHandlerHash::iterator it = menu_eventHandlers_hash()->find(menu);
1012  while (it != menu_eventHandlers_hash()->end() && it.key() == menu) {
1013  RemoveEventHandler(it.value());
1014  ++it;
1015  }
1016  menu_eventHandlers_hash()->remove(menu);
1017  ReleaseMenu(menu);
1018  }
1019 #else
1021  while (actionItems.size()) {
1022  QMacMenuAction *action = actionItems.takeFirst();
1023  if (QMenuMergeList *list = mergeMenuItemsHash.value(action->menu)) {
1024  int i = 0;
1025  while (i < list->size()) {
1026  const QMenuMergeItem &item = list->at(i);
1027  if (item.action == action)
1028  list->removeAt(i);
1029  else
1030  ++i;
1031  }
1032  }
1033  delete action;
1034  }
1036  mergeMenuItemsHash.remove(menu);
1037  [menu release];
1038 #endif
1039 }
1040 
1041 void
1043 {
1044  QMacMenuAction *action = new QMacMenuAction;
1045  action->action = a;
1046  action->ignore_accel = 0;
1047  action->merged = 0;
1048  action->menu = 0;
1049 #ifndef QT_MAC_USE_COCOA
1050  action->command = qt_mac_menu_static_cmd_id++;
1051 #endif
1052  addAction(action, before, qmenu);
1053 }
1054 
1055 void
1057 {
1058 #ifdef QT_MAC_USE_COCOA
1060  Q_UNUSED(qmenu);
1061 #endif
1062  if (!action)
1063  return;
1064  int before_index = actionItems.indexOf(before);
1065  if (before_index < 0) {
1066  before = 0;
1067  before_index = actionItems.size();
1068  }
1069  actionItems.insert(before_index, action);
1070 
1071 #ifndef QT_MAC_USE_COCOA
1072  int index = qt_mac_menu_find_action(menu, action);
1073 #else
1074  [menu retain];
1075  [action->menu release];
1076 #endif
1077  action->menu = menu;
1078 
1079  /* When the action is considered a mergable action it
1080  will stay that way, until removed.. */
1081  if (!qt_mac_no_menubar_merge) {
1082 #ifndef QT_MAC_USE_COCOA
1083  MenuRef merge = 0;
1084  GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu,
1085  sizeof(merge), 0, &merge);
1086 #else
1088 #endif
1089  if (merge) {
1090 #ifndef QT_MAC_USE_COCOA
1091  if (MenuCommand cmd = qt_mac_menu_merge_action(merge, action)) {
1092  action->merged = 1;
1093  action->menu = merge;
1094  action->command = cmd;
1095  if (qt_mac_auto_apple_menu(cmd))
1096  index = 0; //no need
1097 
1098  QMenuMergeList *list = 0;
1099  if (GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
1100  sizeof(list), 0, &list) != noErr || !list) {
1101  list = new QMenuMergeList;
1102  SetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
1103  sizeof(list), &list);
1104  }
1105  list->append(QMenuMergeItem(cmd, action));
1106  }
1107 #else
1108  if (NSMenuItem *cmd = qt_mac_menu_merge_action(merge, action)) {
1109  action->merged = 1;
1110  [merge retain];
1111  [action->menu release];
1112  action->menu = merge;
1113  [cmd retain];
1114  [cmd setAction:@selector(qtDispatcherToQAction:)];
1115  [cmd setTarget:nil];
1116  [action->menuItem release];
1117  action->menuItem = cmd;
1118  QMenuMergeList *list = QMenuPrivate::mergeMenuItemsHash.value(merge);
1119  if (!list) {
1120  list = new QMenuMergeList;
1121  QMenuPrivate::mergeMenuItemsHash.insert(merge, list);
1122  }
1123  list->append(QMenuMergeItem(cmd, action));
1124  }
1125 #endif
1126  }
1127  }
1128 
1129 #ifdef QT_MAC_USE_COCOA
1130  NSMenuItem *newItem = action->menuItem;
1131 #endif
1132  if (
1133 #ifndef QT_MAC_USE_COCOA
1134  index == -1
1135 #else
1136  newItem == 0
1137 #endif
1138  ) {
1139 #ifndef QT_MAC_USE_COCOA
1140  index = before_index;
1141  MenuItemAttributes attr = kMenuItemAttrAutoRepeat;
1142 #else
1143  newItem = createNSMenuItem(action->action->text());
1144  action->menuItem = newItem;
1145 #endif
1146  if (before) {
1147 #ifndef QT_MAC_USE_COCOA
1148  InsertMenuItemTextWithCFString(action->menu, 0, qMax(before_index, 0), attr, action->command);
1149 #else
1150  [menu insertItem:newItem atIndex:qMax(before_index, 0)];
1151 #endif
1152  } else {
1153 #ifndef QT_MAC_USE_COCOA
1154  // Append the menu item to the menu. If it is a kHICommandAbout or a kHICommandAboutQt append
1155  // a separator also (to get a separator above "Preferences"), but make sure that we don't
1156  // add separators between two "about" items.
1157 
1158  // Build a set of all commands that could possibly be before the separator.
1159  QSet<MenuCommand> mergedItems;
1160  mergedItems.insert(kHICommandAbout);
1161  mergedItems.insert(kHICommandAboutQt);
1162  mergedItems.insert(kHICommandCustomMerge);
1163 
1164  QMenuMergeList *list = 0;
1165  if (GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
1166  sizeof(list), 0, &list) == noErr && list) {
1167  for (int i = 0; i < list->size(); ++i) {
1168  MenuCommand command = list->at(i).command;
1169  if (command > kHICommandCustomMerge) {
1170  mergedItems.insert(command);
1171  }
1172  }
1173  }
1174 
1175  const int itemCount = CountMenuItems(action->menu);
1176  MenuItemAttributes testattr;
1177  GetMenuItemAttributes(action->menu, itemCount , &testattr);
1178  if (mergedItems.contains(action->command)
1179  && (testattr & kMenuItemAttrSeparator)) {
1180  InsertMenuItemTextWithCFString(action->menu, 0, qMax(itemCount - 1, 0), attr, action->command);
1181  index = itemCount;
1182  } else {
1183  MenuItemIndex tmpIndex;
1184  AppendMenuItemTextWithCFString(action->menu, 0, attr, action->command, &tmpIndex);
1185  index = tmpIndex;
1186  if (mergedItems.contains(action->command))
1187  AppendMenuItemTextWithCFString(action->menu, 0, kMenuItemAttrSeparator, 0, &tmpIndex);
1188  }
1189 #else
1190  [menu addItem:newItem];
1191 #endif
1192  }
1193 
1194  QWidget *widget = qmenu ? qmenu->widgetItems.value(action->action) : 0;
1195  if (widget) {
1196 #ifndef QT_MAC_USE_COCOA
1197  ChangeMenuAttributes(action->menu, kMenuAttrDoNotCacheImage, 0);
1198  attr = kMenuItemAttrCustomDraw;
1199  SetMenuItemProperty(action->menu, index, kMenuCreatorQt, kMenuPropertyWidgetActionWidget,
1200  sizeof(QWidget *), &widget);
1201  HIViewRef content;
1202  HIMenuGetContentView(action->menu, kThemeMenuTypePullDown, &content);
1203 
1204  EventHandlerRef eventHandlerRef;
1205  InstallMenuEventHandler(action->menu, qt_mac_widget_in_menu_eventHandler,
1206  GetEventTypeCount(widget_in_menu_events),
1207  widget_in_menu_events, 0, &eventHandlerRef);
1208  menu_eventHandlers_hash()->insert(action->menu, eventHandlerRef);
1209 
1210  QWidget *menuWidget = 0;
1211  GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyWidgetMenu,
1212  sizeof(menuWidget), 0, &menuWidget);
1213  if(!menuWidget) {
1214  menuWidget = new QMacNativeWidget(content);
1215  SetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyWidgetMenu,
1216  sizeof(menuWidget), &menuWidget);
1217  menuWidget->show();
1218  }
1219  widget->setParent(menuWidget);
1220 #else
1221  QMacNativeWidget *container = new QMacNativeWidget(0);
1222  container->resize(widget->sizeHint());
1224  widget->setParent(container);
1225 
1226  NSView *containerView = qt_mac_nativeview_for(container);
1227  [containerView setAutoresizesSubviews:YES];
1228  [containerView setAutoresizingMask:NSViewWidthSizable];
1229  [qt_mac_nativeview_for(widget) setAutoresizingMask:NSViewWidthSizable];
1230 
1231  [newItem setView:containerView];
1232  container->show();
1233 #endif
1234  widget->show();
1235  }
1236 
1237  } else {
1238 #ifndef QT_MAC_USE_COCOA
1240 #else
1241  [newItem setEnabled:!QApplicationPrivate::modalState()];
1242 #endif
1243  }
1244 #ifndef QT_MAC_USE_COCOA
1245  SetMenuCommandProperty(action->menu, action->command, kMenuCreatorQt, kMenuPropertyQAction,
1246  sizeof(action), &action);
1247 #else
1248  [newItem setTag:long(static_cast<QAction *>(action->action))];
1249 #endif
1250  syncAction(action);
1251 }
1252 
1253 // return an autoreleased string given a QKeySequence (currently only looks at the first one).
1255 {
1256  quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL));
1257  extern QChar qtKey2CocoaKey(Qt::Key key);
1258  QChar cocoa_key = qtKey2CocoaKey(Qt::Key(accel_key));
1259  if (cocoa_key.isNull())
1260  cocoa_key = QChar(accel_key).toLower().unicode();
1261  return [NSString stringWithCharacters:&cocoa_key.unicode() length:1];
1262 }
1263 
1264 // return the cocoa modifier mask for the QKeySequence (currently only looks at the first one).
1265 NSUInteger keySequenceModifierMask(const QKeySequence &accel)
1266 {
1267  return constructModifierMask(accel[0]);
1268 }
1269 
1270 void
1272 {
1273  if (!action)
1274  return;
1275 
1276 #ifndef QT_MAC_USE_COCOA
1277  const int index = qt_mac_menu_find_action(action->menu, action);
1278  if (index == -1)
1279  return;
1280 #else
1281  NSMenuItem *item = action->menuItem;
1282  if (!item)
1283  return;
1284 #endif
1285 
1286 #ifndef QT_MAC_USE_COCOA
1287  if (!action->action->isVisible()) {
1288  ChangeMenuItemAttributes(action->menu, index, kMenuItemAttrHidden, 0);
1289  return;
1290  }
1291  ChangeMenuItemAttributes(action->menu, index, 0, kMenuItemAttrHidden);
1292 #else
1294  NSMenu *menu = [item menu];
1295  bool actionVisible = action->action->isVisible();
1296  [item setHidden:!actionVisible];
1297  if (!actionVisible)
1298  return;
1299 #endif
1300 
1301 #ifndef QT_MAC_USE_COCOA
1302  if (action->action->isSeparator()) {
1303  ChangeMenuItemAttributes(action->menu, index, kMenuItemAttrSeparator, 0);
1304  return;
1305  }
1306  ChangeMenuItemAttributes(action->menu, index, 0, kMenuItemAttrSeparator);
1307 #else
1308  int itemIndex = [menu indexOfItem:item];
1309  Q_ASSERT(itemIndex != -1);
1310  if (action->action->isSeparator()) {
1311  action->menuItem = [NSMenuItem separatorItem];
1312  [action->menuItem retain];
1313  [menu insertItem: action->menuItem atIndex:itemIndex];
1314  [menu removeItem:item];
1315  [item release];
1316  item = action->menuItem;
1317  return;
1318  } else if ([item isSeparatorItem]) {
1319  // I'm no longer a separator...
1320  action->menuItem = createNSMenuItem(action->action->text());
1321  [menu insertItem:action->menuItem atIndex:itemIndex];
1322  [menu removeItem:item];
1323  [item release];
1324  item = action->menuItem;
1325  }
1326 #endif
1327 
1328  //find text (and accel)
1329  action->ignore_accel = 0;
1330  QString text = action->action->text();
1331  QKeySequence accel = action->action->shortcut();
1332  {
1333  int st = text.lastIndexOf(QLatin1Char('\t'));
1334  if (st != -1) {
1335  action->ignore_accel = 1;
1336  accel = QKeySequence(text.right(text.length()-(st+1)));
1337  text.remove(st, text.length()-st);
1338  }
1339  }
1340  {
1341  QString cmd_text = qt_mac_menu_merge_text(action);
1342  if (!cmd_text.isEmpty()) {
1343  text = cmd_text;
1344  accel = qt_mac_menu_merge_accel(action);
1345  }
1346  }
1347  // Show multiple key sequences as part of the menu text.
1348  if (accel.count() > 1)
1349  text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")");
1350 
1351  QString finalString = qt_mac_removeMnemonics(text);
1352 
1353 #ifndef QT_MAC_USE_COCOA
1354  MenuItemDataRec data;
1355  memset(&data, '\0', sizeof(data));
1356 
1357  //Carbon text
1358  data.whichData |= kMenuItemDataCFString;
1359  QCFString cfstring(finalString); // Hold the reference to the end of the function.
1360  data.cfText = cfstring;
1361 
1362  // Carbon enabled
1363  data.whichData |= kMenuItemDataEnabled;
1364  data.enabled = action->action->isEnabled();
1365  // Carbon icon
1366  data.whichData |= kMenuItemDataIconHandle;
1367  if (!action->action->icon().isNull()
1368  && action->action->isIconVisibleInMenu()) {
1369  data.iconType = kMenuIconRefType;
1370  data.iconHandle = (Handle)qt_mac_create_iconref(action->action->icon().pixmap(16, QIcon::Normal));
1371  } else {
1372  data.iconType = kMenuNoIcon;
1373  }
1374  if (action->action->font().resolve()) { // Carbon font
1375  if (action->action->font().bold())
1376  data.style |= bold;
1377  if (action->action->font().underline())
1378  data.style |= underline;
1379  if (action->action->font().italic())
1380  data.style |= italic;
1381  if (data.style)
1382  data.whichData |= kMenuItemDataStyle;
1383  data.whichData |= kMenuItemDataFontID;
1384  data.fontID = action->action->font().macFontID();
1385  }
1386 #else
1387  // Cocoa Font and title
1388  if (action->action->font().resolve()) {
1389  const QFont &actionFont = action->action->font();
1390  NSFont *customMenuFont = [NSFont fontWithName:qt_mac_QStringToNSString(actionFont.family())
1391  size:actionFont.pointSize()];
1392  NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil];
1393  NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil];
1394  NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
1395  NSAttributedString *str = [[[NSAttributedString alloc] initWithString:qt_mac_QStringToNSString(finalString)
1396  attributes:attributes] autorelease];
1397  [item setAttributedTitle: str];
1398  } else {
1399  [item setTitle: qt_mac_QStringToNSString(finalString)];
1400  }
1401 
1402  if (action->action->menuRole() == QAction::AboutRole || action->action->menuRole() == QAction::QuitRole)
1403  [item setTitle:qt_mac_QStringToNSString(text)];
1404  else
1405  [item setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(text))];
1406 
1407  // Cocoa Enabled
1408  [item setEnabled: action->action->isEnabled()];
1409 
1410  // Cocoa icon
1411  NSImage *nsimage = 0;
1412  if (!action->action->icon().isNull() && action->action->isIconVisibleInMenu()) {
1413  nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(action->action->icon().pixmap(16, QIcon::Normal)));
1414  }
1415  [item setImage:nsimage];
1416  [nsimage release];
1417 #endif
1418 
1419  if (action->action->menu()) { //submenu
1420 #ifndef QT_MAC_USE_COCOA
1421  data.whichData |= kMenuItemDataSubmenuHandle;
1422  data.submenuHandle = action->action->menu()->macMenu();
1423  QWidget *caused = 0;
1424  GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(caused), 0, &caused);
1425  SetMenuItemProperty(data.submenuHandle, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
1426 #else
1427  NSMenu *subMenu = static_cast<NSMenu *>(action->action->menu()->macMenu());
1428  if ([subMenu supermenu] && [subMenu supermenu] != [item menu]) {
1429  // The menu is already a sub-menu of another one. Cocoa will throw an exception,
1430  // in such cases. For the time being, a new QMenu with same set of actions is the
1431  // only workaround.
1432  action->action->setEnabled(false);
1433  } else {
1434  [item setSubmenu:subMenu];
1435  }
1436  [item setAction:nil];
1437 #endif
1438  } else { //respect some other items
1439 #ifndef QT_MAC_USE_COCOA
1440  //shortcuts (say we are setting them all so that we can also clear them).
1441  data.whichData |= kMenuItemDataCmdKey;
1442  data.whichData |= kMenuItemDataCmdKeyModifiers;
1443  data.whichData |= kMenuItemDataCmdKeyGlyph;
1444  if (accel.count() == 1) {
1445  qt_mac_get_accel(accel[0], (quint32*)&data.cmdKeyModifiers, (quint32*)&data.cmdKeyGlyph);
1446  if (data.cmdKeyGlyph == 0)
1447  data.cmdKey = (UniChar)accel[0];
1448  }
1449 #else
1450  [item setSubmenu:0];
1451  if ([item action] == nil)
1452  [item setAction:@selector(qtDispatcherToQAction:)];
1453  // No key equivalent set for multiple key QKeySequence.
1454  if (accel.count() == 1) {
1455  [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)];
1456  [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)];
1457  } else {
1458  [item setKeyEquivalent:@""];
1459  [item setKeyEquivalentModifierMask:NSCommandKeyMask];
1460  }
1461 #endif
1462  }
1463 #ifndef QT_MAC_USE_COCOA
1464  //mark glyph
1465  data.whichData |= kMenuItemDataMark;
1466  if (action->action->isChecked()) {
1467 #if 0
1468  if (action->action->actionGroup() &&
1469  action->action->actionGroup()->isExclusive())
1470  data.mark = diamondMark;
1471  else
1472 #endif
1473  data.mark = checkMark;
1474  } else {
1475  data.mark = noMark;
1476  }
1477 
1478  //actually set it
1479  SetMenuItemData(action->menu, action->command, true, &data);
1480 
1481  // Free up memory
1482  if (data.iconHandle)
1483  ReleaseIconRef(IconRef(data.iconHandle));
1484 #else
1485  //mark glyph
1486  [item setState:action->action->isChecked() ? NSOnState : NSOffState];
1487 #endif
1488 }
1489 
1490 void
1492 {
1493  if (!action)
1494  return;
1495 #ifndef QT_MAC_USE_COCOA
1496  if (action->command == kHICommandQuit || action->command == kHICommandPreferences)
1497  qt_mac_command_set_enabled(action->menu, action->command, false);
1498  else
1499  DeleteMenuItem(action->menu, qt_mac_menu_find_action(action->menu, action));
1500 #else
1502  if (action->merged) {
1503  if (reinterpret_cast<QAction *>([action->menuItem tag]) == action->action) {
1504  QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
1505  [action->menuItem setEnabled:false];
1506  if (action->menuItem != [loader quitMenuItem]
1507  && action->menuItem != [loader preferencesMenuItem]) {
1508  [[action->menuItem menu] removeItem:action->menuItem];
1509  }
1510  if (QMenuMergeList *list = mergeMenuItemsHash.value(action->menu)) {
1511  int i = 0;
1512  while (i < list->size()) {
1513  const QMenuMergeItem &item = list->at(i);
1514  if (item.action == action)
1515  list->removeAt(i);
1516  else
1517  ++i;
1518  }
1519  }
1520  }
1521  } else {
1522  [[action->menuItem menu] removeItem:action->menuItem];
1523  }
1524 #endif
1525  actionItems.removeAll(action);
1526 }
1527 
1528 OSMenuRef
1530 {
1531  Q_UNUSED(merge);
1532  Q_Q(QMenu);
1533  if (mac_menu && mac_menu->menu)
1534  return mac_menu->menu;
1535  if (!mac_menu)
1536  mac_menu = new QMacMenuPrivate;
1538  if (merge) {
1539 #ifndef QT_MAC_USE_COCOA
1540  SetMenuItemProperty(mac_menu->menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu, sizeof(merge), &merge);
1541 #else
1542  mergeMenuHash.insert(mac_menu->menu, merge);
1543 #endif
1544  }
1545  QList<QAction*> items = q->actions();
1546  for(int i = 0; i < items.count(); i++)
1547  mac_menu->addAction(items[i], 0, this);
1549  return mac_menu->menu;
1550 }
1551 
1555 void
1557 {
1558 #ifndef QT_MAC_USE_COCOA
1559  if (collapse)
1560  ChangeMenuAttributes(mac_menu->menu, kMenuAttrCondenseSeparators, 0);
1561  else
1562  ChangeMenuAttributes(mac_menu->menu, 0, kMenuAttrCondenseSeparators);
1563 #else
1564  qt_mac_menu_collapseSeparators(mac_menu->menu, collapse);
1565 #endif
1566 }
1567 
1568 
1569 
1570 #ifndef QT_MAC_USE_COCOA
1571 
1575 {
1576  if (!macMenu(0))
1577  return;
1578 
1580  if (enable) {
1581  for (int i = 0; i < mac_menu->actionItems.count(); ++i) {
1582  QMacMenuAction *menuItem = mac_menu->actionItems.at(i);
1583  if (menuItem && menuItem->action && menuItem->action->isEnabled()) {
1584  // Only enable those items which contains an enabled QAction.
1585  // i == 0 -> the menu itself, hence i + 1 for items.
1586  EnableMenuItem(mac_menu->menu, i + 1);
1587  }
1588  }
1589  } else {
1590  DisableAllMenuItems(mac_menu->menu);
1591  }
1592 }
1593 #endif
1594 
1610 OSMenuRef QMenu::macMenu(OSMenuRef merge) { return d_func()->macMenu(merge); }
1611 
1612 /*****************************************************************************
1613  QMenuBar bindings
1614  *****************************************************************************/
1616 Q_GLOBAL_STATIC(MenuBarHash, menubars)
1617 static QMenuBar *fallback = 0;
1619 {
1620 }
1621 
1623 {
1625  delete (*it);
1626 #ifndef QT_MAC_USE_COCOA
1627  if (apple_menu) {
1628  QMenuMergeList *list = 0;
1629  GetMenuItemProperty(apple_menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
1630  sizeof(list), 0, &list);
1631  if (list) {
1632  RemoveMenuItemProperty(apple_menu, 0, kMenuCreatorQt, kMenuPropertyMergeList);
1633  delete list;
1634  }
1635  ReleaseMenu(apple_menu);
1636  }
1637  if (menu)
1638  ReleaseMenu(menu);
1639 #else
1640  [apple_menu release];
1641  [menu release];
1642 #endif
1643 }
1644 
1645 void
1647 {
1648  if (a->isSeparator() || !menu)
1649  return;
1650  QMacMenuAction *action = new QMacMenuAction;
1651  action->action = a;
1652  action->ignore_accel = 1;
1653 #ifndef QT_MAC_USE_COCOA
1654  action->command = qt_mac_menu_static_cmd_id++;
1655 #endif
1656  addAction(action, findAction(before));
1657 }
1658 
1659 void
1661 {
1662  if (!action || !menu)
1663  return;
1664 
1665  int before_index = actionItems.indexOf(before);
1666  if (before_index < 0) {
1667  before = 0;
1668  before_index = actionItems.size();
1669  }
1670  actionItems.insert(before_index, action);
1671 
1672  MenuItemIndex index = actionItems.size()-1;
1673 
1674  action->menu = menu;
1675 #ifdef QT_MAC_USE_COCOA
1677  [action->menu retain];
1678  NSMenuItem *newItem = createNSMenuItem(action->action->text());
1679  action->menuItem = newItem;
1680 #endif
1681  if (before) {
1682 #ifndef QT_MAC_USE_COCOA
1683  InsertMenuItemTextWithCFString(action->menu, 0, qMax(1, before_index+1), 0, action->command);
1684 #else
1685  [menu insertItem:newItem atIndex:qMax(1, before_index + 1)];
1686 #endif
1687  index = before_index;
1688  } else {
1689 #ifndef QT_MAC_USE_COCOA
1690  AppendMenuItemTextWithCFString(action->menu, 0, 0, action->command, &index);
1691 #else
1692  [menu addItem:newItem];
1693 #endif
1694  }
1695 #ifndef QT_MAC_USE_COCOA
1696  SetMenuItemProperty(action->menu, index, kMenuCreatorQt, kMenuPropertyQAction, sizeof(action),
1697  &action);
1698 #else
1699  [newItem setTag:long(static_cast<QAction *>(action->action))];
1700 #endif
1701  syncAction(action);
1702 }
1703 
1704 void
1706 {
1707  if (!action || !menu)
1708  return;
1709 #ifndef QT_MAC_USE_COCOA
1710  const int index = qt_mac_menu_find_action(action->menu, action);
1711 #else
1713  NSMenuItem *item = action->menuItem;
1714 #endif
1715 
1716  OSMenuRef submenu = 0;
1717  bool release_submenu = false;
1718  if (action->action->menu()) {
1719  if ((submenu = action->action->menu()->macMenu(apple_menu))) {
1720 #ifndef QT_MAC_USE_COCOA
1721  QWidget *caused = 0;
1722  GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(caused), 0, &caused);
1723  SetMenuItemProperty(submenu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
1724 #else
1725  if ([submenu supermenu] && [submenu supermenu] != [item menu])
1726  return;
1727  else
1728  [item setSubmenu:submenu];
1729 #endif
1730  }
1731 #ifndef QT_MAC_USE_COCOA
1732  } else { // create a submenu to act as menu
1733  release_submenu = true;
1734  CreateNewMenu(0, 0, &submenu);
1735 #endif
1736  }
1737 
1738  if (submenu) {
1739  bool visible = actualMenuItemVisibility(this, action);
1740 #ifndef QT_MAC_USE_COCOA
1741  SetMenuItemHierarchicalMenu(action->menu, index, submenu);
1742  SetMenuTitleWithCFString(submenu, QCFString(qt_mac_removeMnemonics(action->action->text())));
1743  if (visible)
1744  ChangeMenuAttributes(submenu, 0, kMenuAttrHidden);
1745  else
1746  ChangeMenuAttributes(submenu, kMenuAttrHidden, 0);
1747 #else
1748  [item setSubmenu: submenu];
1749  [submenu setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(action->action->text()))];
1750  syncNSMenuItemVisiblity(item, visible);
1751  syncNSMenuItemEnabled(item, action->action->isEnabled());
1752 #endif
1753  if (release_submenu) { //no pointers to it
1754 #ifndef QT_MAC_USE_COCOA
1755  ReleaseMenu(submenu);
1756 #else
1757  [submenu release];
1758 #endif
1759  }
1760  } else {
1761  qWarning("QMenu: No OSMenuRef created for popup menu");
1762  }
1763 }
1764 
1765 void
1767 {
1768  if (!action || !menu)
1769  return;
1770 #ifndef QT_MAC_USE_COCOA
1771  DeleteMenuItem(action->menu, qt_mac_menu_find_action(action->menu, action));
1772 #else
1774  [action->menu removeItem:action->menuItem];
1775 #endif
1776  actionItems.removeAll(action);
1777 }
1778 
1780 {
1781  // This function is different from q->isNativeMenuBar(), as
1782  // it returns true only if a native menu bar is actually
1783  // _created_.
1784  if (!widget)
1785  return false;
1786  return menubars()->contains(widget->window());
1787 }
1788 
1789 void
1791 {
1792  Q_Q(QMenuBar);
1793  static int dontUseNativeMenuBar = -1;
1794  // We call the isNativeMenuBar function here
1795  // because that will make sure that local overrides
1796  // are dealt with correctly. q->isNativeMenuBar() will, if not
1797  // overridden, depend on the attribute Qt::AA_DontUseNativeMenuBar:
1798  bool qt_mac_no_native_menubar = !q->isNativeMenuBar();
1799  if (qt_mac_no_native_menubar == false && dontUseNativeMenuBar < 0) {
1800  // The menubar is set to be native. Let's check (one time only
1801  // for all menubars) if this is OK with the rest of the environment.
1802  // As a result, Qt::AA_DontUseNativeMenuBar is set. NB: the application
1803  // might still choose to not respect, or change, this flag.
1805  bool environmentSaysNo = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty();
1806  dontUseNativeMenuBar = isPlugin || environmentSaysNo;
1808  qt_mac_no_native_menubar = !q->isNativeMenuBar();
1809  }
1810  if (qt_mac_no_native_menubar == false) {
1811  // INVARIANT: Use native menubar.
1812  extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp
1814  if (!parent && !fallback) {
1815  fallback = q;
1816  mac_menubar = new QMacMenuBarPrivate;
1817  } else if (parent && parent->isWindow()) {
1818  menubars()->insert(q->window(), q);
1819  mac_menubar = new QMacMenuBarPrivate;
1820  }
1821  }
1822 }
1823 
1825 {
1826  Q_Q(QMenuBar);
1828  if (fallback == q)
1829  fallback = 0;
1830  delete mac_menubar;
1831  QWidget *tlw = q->window();
1832  menubars()->remove(tlw);
1833  mac_menubar = 0;
1834 
1835  if (!qt_mac_current_menubar.qmenubar || qt_mac_current_menubar.qmenubar == q) {
1836 #ifdef QT_MAC_USE_COCOA
1837  QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
1838  [loader removeActionsFromAppMenu];
1839 #else
1841 #endif
1842  extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp
1844  }
1845 }
1846 
1848 {
1849  Q_Q(QMenuBar);
1850  if (!q->isNativeMenuBar() || !mac_menubar) {
1851  return 0;
1852  } else if (!mac_menubar->menu) {
1853  mac_menubar->menu = qt_mac_create_menu(q);
1854 #ifdef QT_MAC_USE_COCOA
1855  [mac_menubar->menu setAutoenablesItems:NO];
1856 #endif
1857  ProcessSerialNumber mine, front;
1858  if (GetCurrentProcess(&mine) == noErr && GetFrontProcess(&front) == noErr) {
1859  if (!qt_mac_no_menubar_merge && !mac_menubar->apple_menu) {
1860  mac_menubar->apple_menu = qt_mac_create_menu(q);
1861 #ifndef QT_MAC_USE_COCOA
1862  MenuItemIndex index;
1863  AppendMenuItemTextWithCFString(mac_menubar->menu, 0, 0, 0, &index);
1864 
1865  SetMenuTitleWithCFString(mac_menubar->apple_menu, QCFString(QString(QChar(0x14))));
1866  SetMenuItemHierarchicalMenu(mac_menubar->menu, index, mac_menubar->apple_menu);
1867  SetMenuItemProperty(mac_menubar->apple_menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(q), &q);
1868 #else
1869  [mac_menubar->apple_menu setTitle:qt_mac_QStringToNSString(QString(QChar(0x14)))];
1870  NSMenuItem *apple_menuItem = [[NSMenuItem alloc] init];
1871  [apple_menuItem setSubmenu:mac_menubar->menu];
1872  [mac_menubar->apple_menu addItem:apple_menuItem];
1873  [apple_menuItem release];
1874 #endif
1875  }
1876  if (mac_menubar->apple_menu) {
1877 #ifndef QT_MAC_USE_COCOA
1878  SetMenuItemProperty(mac_menubar->menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu,
1879  sizeof(mac_menubar->apple_menu), &mac_menubar->apple_menu);
1880 #else
1881  QMenuPrivate::mergeMenuHash.insert(mac_menubar->menu, mac_menubar->apple_menu);
1882 #endif
1883  }
1884  QList<QAction*> items = q->actions();
1885  for(int i = 0; i < items.count(); i++)
1886  mac_menubar->addAction(items[i]);
1887  }
1888  }
1889  return mac_menubar->menu;
1890 }
1891 
1903 OSMenuRef QMenuBar::macMenu() { return d_func()->macMenu(); }
1904 
1905 /* !
1906  \internal
1907  Ancestor function that crosses windows (QWidget::isAncestorOf
1908  only considers widgets within the same window).
1909 */
1910 static bool qt_mac_is_ancestor(QWidget* possibleAncestor, QWidget *child)
1911 {
1912  if (!possibleAncestor)
1913  return false;
1914 
1915  QWidget * current = child->parentWidget();
1916  while (current != 0) {
1917  if (current == possibleAncestor)
1918  return true;
1919  current = current->parentWidget();
1920  }
1921  return false;
1922 }
1923 
1924 /* !
1925  \internal
1926  Returns true if the entries of menuBar should be disabled,
1927  based on the modality type of modalWidget.
1928 */
1930 {
1931  QWidget *modalWidget = qApp->activeModalWidget();
1932  if (!modalWidget)
1933  return false;
1934 
1935  if (menuBar && menuBar == menubars()->value(modalWidget))
1936  // The menu bar is owned by the modal widget.
1937  // In that case we should enable it:
1938  return false;
1939 
1940  // When there is an application modal window on screen, the entries of
1941  // the menubar should be disabled. The exception in Qt is that if the
1942  // modal window is the only window on screen, then we enable the menu bar.
1943  QWidget *w = modalWidget;
1945  while (w) {
1946  if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) {
1947  for (int i=0; i<topLevelWidgets.size(); ++i) {
1948  QWidget *top = topLevelWidgets.at(i);
1949  if (w != top && top->isVisible()) {
1950  // INVARIANT: we found another visible window
1951  // on screen other than our modalWidget. We therefore
1952  // disable the menu bar to follow normal modality logic:
1953  return true;
1954  }
1955  }
1956  // INVARIANT: We have only one window on screen that happends
1957  // to be application modal. We choose to enable the menu bar
1958  // in that case to e.g. enable the quit menu item.
1959  return false;
1960  }
1961  w = w->parentWidget();
1962  }
1963 
1964  // INVARIANT: modalWidget is window modal. Disable menu entries
1965  // if the menu bar belongs to an ancestor of modalWidget. If menuBar
1966  // is nil, we understand it as the default menu bar set by the nib:
1967  return menuBar ? qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget) : false;
1968 }
1969 
1971 {
1972  QWidget *w = qApp->activeWindow();
1973  if (!w) {
1974  // We have no active window on screen. Try to
1975  // find a window from the list of top levels:
1977  for(int i = 0; i < tlws.size(); ++i) {
1978  QWidget *tlw = tlws.at(i);
1979  if ((tlw->isVisible() && tlw->windowType() != Qt::Tool &&
1980  tlw->windowType() != Qt::Popup)) {
1981  w = tlw;
1982  break;
1983  }
1984  }
1985  }
1986  return w;
1987 }
1988 
1990 {
1991  QMenuBar *mb = 0;
1992  if (w) {
1993  mb = menubars()->value(w);
1994 #ifndef QT_NO_MAINWINDOW
1995  QDockWidget *dw = qobject_cast<QDockWidget *>(w);
1996  if (!mb && dw) {
1998  if (mw && (mb = menubars()->value(mw)))
1999  w = mw;
2000  }
2001 #endif
2002  while(w && !mb)
2003  mb = menubars()->value((w = w->parentWidget()));
2004  }
2005 
2006  if (!mb) {
2007  // We could not find a menu bar for the window. Lets
2008  // check if we have a global (parentless) menu bar instead:
2009  mb = fallback;
2010  }
2011 
2012  return mb;
2013 }
2014 
2016 {
2018  return;
2019 
2020 #ifndef QT_MAC_USE_COCOA
2021  MenuRef clear_menu = 0;
2022  if (CreateNewMenu(0, 0, &clear_menu) == noErr) {
2023  SetRootMenu(clear_menu);
2024  ReleaseMenu(clear_menu);
2025  } else {
2026  qWarning("QMenu: Internal error at %s:%d", __FILE__, __LINE__);
2027  }
2028  ClearMenuBar();
2029  qt_mac_command_set_enabled(0, kHICommandPreferences, false);
2030  InvalMenuBar();
2031 #else
2033  QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
2034  NSMenu *menu = [loader menu];
2035  [loader ensureAppMenuInMenu:menu];
2036  [NSApp setMainMenu:menu];
2037  const bool modal = qt_mac_should_disable_menu(0);
2038  if (qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal)
2039  qt_mac_set_modal_state(menu, modal);
2040  qt_mac_current_menubar.qmenubar = 0;
2041  qt_mac_current_menubar.modal = modal;
2042 #endif
2043 }
2044 
2056 {
2057 #ifdef QT_MAC_USE_COCOA
2059  qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar));
2060  return true;
2061 #else
2063 #endif
2064 }
2065 
2067 {
2068  bool ret = false;
2071  QMenuBar *mb = findMenubarForWindow(w);
2072  extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
2073 
2074  // We need to see if we are in full screen mode, if so we need to
2075  // switch the full screen mode to be able to show or hide the menubar.
2076  if(w && mb) {
2077  // This case means we are creating a menubar, check if full screen
2078  if(w->isFullScreen()) {
2079  // Ok, switch to showing the menubar when hovering over it.
2080  SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
2081  qt_mac_app_fullscreen = true;
2082  }
2083  } else if(w) {
2084  // Removing a menubar
2085  if(w->isFullScreen()) {
2086  // Ok, switch to not showing the menubar when hovering on it
2087  SetSystemUIMode(kUIModeAllHidden, 0);
2088  qt_mac_app_fullscreen = true;
2089  }
2090  }
2091 
2092  if (mb && mb->isNativeMenuBar()) {
2094 #ifdef QT_MAC_USE_COCOA
2096 #endif
2097  if (OSMenuRef menu = mb->macMenu()) {
2098 #ifndef QT_MAC_USE_COCOA
2099  SetRootMenu(menu);
2100 #else
2101  QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
2102  [loader ensureAppMenuInMenu:menu];
2103  [NSApp setMainMenu:menu];
2104  syncMenuBarItemsVisiblity(mb->d_func()->mac_menubar);
2105 
2106  if (OSMenuRef tmpMerge = QMenuPrivate::mergeMenuHash.value(menu)) {
2107  if (QMenuMergeList *mergeList
2108  = QMenuPrivate::mergeMenuItemsHash.value(tmpMerge)) {
2109  const int mergeListSize = mergeList->size();
2110 
2111  for (int i = 0; i < mergeListSize; ++i) {
2112  const QMenuMergeItem &mergeItem = mergeList->at(i);
2113  // Ideally we would call QMenuPrivate::syncAction, but that requires finding
2114  // the original QMen and likely doing more work than we need.
2115  // For example, enabled is handled below.
2116  [mergeItem.menuItem setTag:reinterpret_cast<long>(
2117  static_cast<QAction *>(mergeItem.action->action))];
2118  [mergeItem.menuItem setHidden:!(mergeItem.action->action->isVisible())];
2119  }
2120  }
2121  }
2122 #endif
2123  // Check if menu is modally shaddowed and should be disabled:
2124  modal = qt_mac_should_disable_menu(mb);
2125  if (mb != qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal)
2126  qt_mac_set_modal_state(menu, modal);
2127  }
2128  qt_mac_current_menubar.qmenubar = mb;
2129  qt_mac_current_menubar.modal = modal;
2130  ret = true;
2131  } else if (qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
2132  // INVARIANT: The currently active menu bar (if any) is not native. But we do have a
2133  // native menu bar from before. So we need to decide whether or not is should be enabled:
2135  if (modal != qt_mac_current_menubar.modal) {
2136  ret = true;
2137  if (OSMenuRef menu = qt_mac_current_menubar.qmenubar->macMenu()) {
2138 #ifndef QT_MAC_USE_COCOA
2139  SetRootMenu(menu);
2140 #else
2141  QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
2142  [loader ensureAppMenuInMenu:menu];
2143  [NSApp setMainMenu:menu];
2144  syncMenuBarItemsVisiblity(qt_mac_current_menubar.qmenubar->d_func()->mac_menubar);
2145 #endif
2146  qt_mac_set_modal_state(menu, modal);
2147  }
2148  qt_mac_current_menubar.modal = modal;
2149  }
2150  }
2151 
2152  if (!ret) {
2154  }
2155  return ret;
2156 }
2157 
2160 
2162 {
2163 #ifndef QT_MAC_USE_COCOA
2164  MenuRef merge = 0;
2165  GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu,
2166  sizeof(merge), 0, &merge);
2167  if (merge) {
2168  QMenuMergeList *list = 0;
2169  if (GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
2170  sizeof(list), 0, &list) == noErr && list) {
2171  for(int i = 0; i < list->size(); ++i) {
2172  QMenuMergeItem item = list->at(i);
2173  if (item.action->action == action)
2174  return true;
2175  }
2176  }
2177  }
2178 #else
2179  if (OSMenuRef merge = mergeMenuHash.value(menu)) {
2180  if (QMenuMergeList *list = mergeMenuItemsHash.value(merge)) {
2181  for(int i = 0; i < list->size(); ++i) {
2182  const QMenuMergeItem &item = list->at(i);
2183  if (item.action->action == action)
2184  return true;
2185  }
2186  }
2187  }
2188 #endif
2189  return false;
2190 }
2191 
2192 //creation of the OSMenuRef
2194 {
2195  OSMenuRef ret;
2196 #ifndef QT_MAC_USE_COCOA
2197  ret = 0;
2198  if (CreateNewMenu(0, 0, &ret) == noErr) {
2200  SetMenuItemProperty(ret, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(w), &w);
2201 
2202  // kEventMenuMatchKey is only sent to the menu itself and not to
2203  // the application, install a separate handler for that event.
2204  EventHandlerRef eventHandlerRef;
2205  InstallMenuEventHandler(ret, qt_mac_menu_event,
2206  GetEventTypeCount(menu_menu_events),
2207  menu_menu_events, 0, &eventHandlerRef);
2208  menu_eventHandlers_hash()->insert(ret, eventHandlerRef);
2209  } else {
2210  qWarning("QMenu: Internal error");
2211  }
2212 #else
2213  if (QMenu *qmenu = qobject_cast<QMenu *>(w)){
2214  ret = [[QT_MANGLE_NAMESPACE(QCocoaMenu) alloc] initWithQMenu:qmenu];
2215  } else {
2216  ret = [[NSMenu alloc] init];
2217  }
2218 #endif
2219  return ret;
2220 }
2221 
2222 
2223 
2225 
bool isSeparator() const
Returns true if this action is a separator action; otherwise it returns false.
Definition: qaction.cpp:839
static void cancelAllMenuTracking()
Definition: qmenu_mac.mm:178
uchar ignore_accel
Definition: qmenu_p.h:106
T qobject_cast(QObject *object)
Definition: qobject.h:375
The QMultiHash class is a convenience QHash subclass that provides multi-valued hashes.
Definition: qcontainerfwd.h:58
uint command
Definition: qmenu_p.h:102
static bool actualMenuItemVisibility(const QMenuBarPrivate::QMacMenuBarPrivate *mbp, const QMacMenuAction *action)
Definition: qmenu_mac.mm:194
void removeAction(QMacMenuAction *)
Definition: qmenu_mac.mm:1766
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
static EventTypeSpec menu_events[]
Definition: qmenu_mac.mm:385
static QKeySequence qt_mac_menu_merge_accel(QMacMenuAction *action)
Definition: qmenu_mac.mm:955
bool isEnabled() const
Definition: qaction.cpp:1208
static bool qt_mac_should_disable_menu(QMenuBar *menuBar)
Definition: qmenu_mac.mm:1929
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
static QWidgetList topLevelWidgets()
The QKeyEvent class describes a key event.
Definition: qevent.h:224
static void qt_mac_cleanup_menu_event()
Definition: qmenu_mac.mm:523
static QMenuBar * findMenubarForWindow(QWidget *w)
Definition: qmenu_mac.mm:1989
bool qt_mac_no_menubar_merge
Definition: qmenu_mac.mm:74
bool merged(const QAction *action) const
Definition: qmenu_mac.mm:2161
int type
Definition: qmetatype.cpp:239
static QString qt_mac_menu_merge_text(QMacMenuAction *action)
Definition: qmenu_mac.mm:920
unsigned char c[8]
Definition: qnumeric_p.h:62
static void qt_mac_set_modal_state(OSMenuRef menu, bool on)
Definition: qmenu_mac.mm:701
uint collapsibleSeparators
Definition: qmenu_p.h:201
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void syncSeparatorsCollapsible(bool collapsible)
Definition: qmenu_mac.mm:1556
void setParent(QWidget *parent)
Sets the parent of the widget to parent, and resets the window flags.
Definition: qwidget.cpp:10479
EventRef event
QPointer< QWidget > widget
int remove(const Key &key)
Removes all the items that have the key from the hash.
Definition: qhash.h:784
QKeySequence shortcut
the action&#39;s primary shortcut key
Definition: qaction.h:83
The QDockWidget class provides a widget that can be docked inside a QMainWindow or floated as a top-l...
Definition: qdockwidget.h:60
The QRegExp class provides pattern matching using regular expressions.
Definition: qregexp.h:61
bool showStatusText(QWidget *widget=0)
Updates the relevant status bar for the widget specified by sending a QStatusTipEvent to its parent w...
Definition: qaction.cpp:1315
void activate(ActionEvent event)
Sends the relevant signals for ActionEvent event.
Definition: qaction.cpp:1326
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
bool isNull() const
Returns true if the character is the Unicode character 0x0000 (&#39;\0&#39;); otherwise returns false...
Definition: qchar.h:262
#define it(className, varName)
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
static quint32 constructModifierMask(quint32 accel_key)
Definition: qmenu_mac.mm:145
bool underline() const
Returns true if underline has been set; otherwise returns false.
Definition: qfont.cpp:1320
bool isVisible() const
Definition: qwidget.h:1005
ActionEvent
This enum type is used when calling QAction::activate()
Definition: qaction.h:176
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
QMacMenuAction * action
Definition: qmenu_p.h:121
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
static void setAttribute(Qt::ApplicationAttribute attribute, bool on=true)
Sets the attribute attribute if on is true; otherwise clears the attribute.
QString text
the action&#39;s descriptive text
Definition: qaction.h:76
OSMenuRef macMenu(OSMenuRef merge=0)
Definition: qmenu_mac.mm:1610
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
QList< QMacMenuAction * > actionItems
Definition: qmenu_p.h:308
NSUInteger keySequenceModifierMask(const QKeySequence &accel)
Definition: qmenu_mac.mm:1265
static EventHandlerUPP mac_menu_eventUPP
Definition: qmenu_mac.mm:522
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
void insert(int i, const T &t)
Inserts value at index position i in the list.
Definition: qlist.h:575
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
static QApplicationPrivate * instance()
void * qt_mac_create_nsimage(const QPixmap &pm)
long ASN1_INTEGER_get ASN1_INTEGER * a
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
void init()
Definition: qmenu.cpp:155
T & value() const
Returns a modifiable reference to the current item&#39;s value.
Definition: qhash.h:348
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qwidget.h:1017
MenuCommand command
Definition: qmenu_p.h:116
The QString class provides a Unicode character string.
Definition: qstring.h:83
bool qt_mac_quit_menu_item_enabled
Definition: qmenu_mac.mm:75
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
NSString * keySequenceToKeyEqivalent(const QKeySequence &accel)
Definition: qmenu_mac.mm:1254
IconRef qt_mac_create_iconref(const QPixmap &px)
static void qt_mac_command_set_enabled(MenuRef menu, UInt32 cmd, bool b)
Definition: qmenu_mac.mm:547
void addAction(QAction *, QAction *=0)
Definition: qmenu_mac.mm:1646
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QStringList keys
static QHash< OSMenuRef, OSMenuRef > mergeMenuHash
Definition: qmenu_p.h:334
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
void setEnabled(bool)
Definition: qaction.cpp:1192
QString qAppName()
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QString qt_mac_removeMnemonics(const QString &original)
MenuRole menuRole
the action&#39;s menu role
Definition: qaction.h:88
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
void macCreateMenuBar(QWidget *)
Definition: qmenu_mac.mm:1790
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
static QWidget * focus_widget
#define Q_Q(Class)
Definition: qglobal.h:2483
void NSMenuItem
Definition: qmenu_p.h:80
bool isVisible() const
Definition: qaction.cpp:1246
static EventHandlerRef mac_menu_event_handler
Definition: qmenu_mac.mm:521
QWidgetData data
Definition: qwidget_p.h:755
static MenuCommand qt_mac_menu_merge_action(MenuRef merge, QMacMenuAction *action)
Definition: qmenu_mac.mm:779
#define SIGNAL(a)
Definition: qobjectdefs.h:227
QFont resolve(const QFont &) const
Returns a new QFont that has attributes copied from other that have not been previously set on this f...
Definition: qfont.cpp:1983
int width() const
Returns the width.
Definition: qsize.h:126
static QWidget * findWindowThatShouldDisplayMenubar()
Definition: qmenu_mac.mm:1970
static EventTypeSpec widget_in_menu_events[]
Definition: qmenu_mac.mm:305
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
bool isNativeMenuBar() const
Definition: qmenubar.cpp:2095
bool isIconVisibleInMenu() const
Definition: qaction.cpp:1651
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static void qt_mac_get_accel(quint32 accel_key, quint32 *modif, quint32 *key)
Definition: qmenu_mac.mm:568
bool isAccepted() const
Definition: qcoreevent.h:307
QList< QMacMenuAction * > actionItems
Definition: qmenubar_p.h:196
QString qt_mac_applicationmenu_string(int type)
em>Reimplemented Function
WindowRef OSWindowRef
bool contains(const T &value) const
Definition: qset.h:91
T takeFirst()
Removes the first item in the list and returns it.
Definition: qlist.h:489
const UInt32 kMenuCreatorQt
Definition: qmenu_mac.mm:82
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static struct @304 qt_mac_current_menubar
#define qApp
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
QHash< QAction *, QWidget * > widgetItems
Definition: qmenu_p.h:195
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
OSMenuRef menu
Definition: qmenu_p.h:109
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
struct OpaqueControlRef * HIViewRef
#define emit
Definition: qobjectdefs.h:76
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition: qicon.cpp:769
Qt::WindowModality windowModality
which windows are blocked by the modal widget
Definition: qwidget.h:156
void syncAction(QMacMenuAction *)
Definition: qmenu_mac.mm:1271
QMacMenuAction * findAction(QAction *a)
Definition: qmenu_p.h:320
QFont font
the action&#39;s font
Definition: qaction.h:81
Q_CORE_EXPORT void qWarning(const char *,...)
QIcon icon
the action&#39;s icon
Definition: qaction.h:75
void Q_GUI_EXPORT qt_mac_set_menubar_merge(bool b)
Definition: qmenu_mac.mm:981
const_iterator insert(const T &value)
Definition: qset.h:179
int receivers(const char *signal) const
Returns the number of receivers connected to the signal.
Definition: qobject.cpp:2406
unsigned int uint
Definition: qglobal.h:996
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
bool qt_mac_menubar_is_open()
Definition: qmenu_mac.mm:750
bool qt_mac_watchingAboutToShow(QMenu *menu)
Definition: qmenu_mac.mm:119
QString toString(SequenceFormat format=PortableText) const
Return a string representation of the key sequence, based on format.
QString right(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n rightmost characters of the string.
Definition: qstring.cpp:3682
const Key & key() const
Returns the current item&#39;s key as a const reference.
Definition: qhash.h:347
void show()
Shows the widget and its child widgets.
signed long OSStatus
struct OpaqueRgnHandle * RgnHandle
void macDestroyMenuBar()
Definition: qmenu_mac.mm:1824
static QWidgetList topLevelWidgets()
Returns a list of the top-level widgets (windows) in the application.
struct OpaqueEventRef * EventRef
MenuRef OSMenuRef
static int qt_mac_CountMenuItems(OSMenuRef menu)
Definition: qmenu_mac.mm:124
The QList::iterator class provides an STL-style non-const iterator for QList and QQueue.
Definition: qlist.h:181
void Q_GUI_EXPORT qt_mac_set_menubar_icons(bool b)
Definition: qmenu_mac.mm:977
void Q_GUI_EXPORT qt_mac_set_native_menubar(bool b)
Definition: qmenu_mac.mm:979
static bool macUpdateMenuBarImmediatly()
Definition: qmenu_mac.mm:2066
bool bold() const
Returns true if weight() is a value greater than QFont::Normal ; otherwise returns false...
Definition: qfont.h:348
QPointer< QMenuBar > qmenubar
Definition: qmenu_mac.mm:98
static EventTypeSpec menu_menu_events[]
Definition: qmenu_mac.mm:393
static int qt_mac_menu_find_action(MenuRef menu, MenuCommand cmd)
Definition: qmenu_mac.mm:287
QMenu * menu() const
Returns the menu contained by this action.
Definition: qaction.cpp:793
void removeAction(QMacMenuAction *)
Definition: qmenu_mac.mm:1491
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
The QMenuBar class provides a horizontal menu bar.
Definition: qmenubar.h:62
The QKeySequence class encapsulates a key sequence as used by shortcuts.
Definition: qkeysequence.h:72
void qt_mac_dispose_rgn(RgnHandle r)
int indexOf(const T &t, int from=0) const
Returns the index position of the first occurrence of value in the list, searching forward from index...
Definition: qlist.h:847
The QMenu class provides a menu widget for use in menu bars, context menus, and other popup menus...
Definition: qmenu.h:72
void resize(int w, int h)
This corresponds to resize(QSize(w, h)).
Definition: qwidget.h:1014
static OSMenuRef qt_mac_create_menu(QWidget *w)
Definition: qmenu_mac.mm:2193
static bool qt_mac_is_ancestor(QWidget *possibleAncestor, QWidget *child)
Definition: qmenu_mac.mm:1910
The QFont class specifies a font used for drawing text.
Definition: qfont.h:64
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
#define QT_MANGLE_NAMESPACE(name)
Definition: qglobal.h:106
int lastIndexOf(QChar c, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:3000
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
QString family() const
Returns the requested font family name, i.e.
Definition: qfont.cpp:906
bool qt_mac_app_fullscreen
#define st(var, type, card)
int key
QString toLower() const Q_REQUIRED_RESULT
Returns a lowercase copy of the string.
Definition: qstring.cpp:5389
bool isFullScreen() const
Definition: qwidget.cpp:3153
The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
Definition: qhash.h:330
unsigned int quint32
Definition: qglobal.h:938
The QMainWindow class provides a main application window.
Definition: qmainwindow.h:63
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
RgnHandle qt_mac_get_rgn()
QList< QAction * > actions() const
Returns the (possibly empty) list of this widget&#39;s actions.
Definition: qwidget.cpp:3407
int height() const
Returns the height.
Definition: qsize.h:129
if(void) toggleToolbarShown
static bool native_modal_dialog_active
QFactoryLoader * l
static bool macUpdateMenuBar()
Definition: qmenu_mac.mm:2055
OSViewRef qt_mac_nativeview_for(const QWidget *)
Definition: qwidget_mac.mm:419
uint count() const
Returns the number of keys in the key sequence.
QChar qtKey2CocoaKey(Qt::Key key)
bool isChecked() const
Definition: qaction.cpp:1151
struct OpaqueMenuRef * MenuRef
OSMenuRef macMenu()
Definition: qmenu_mac.mm:1903
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
MenuRole
This enum describes how an action should be moved into the application menu on Mac OS X...
Definition: qaction.h:94
quint16 index
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
QObject * parent
Definition: qobject.h:92
bool macWidgetHasNativeMenubar(QWidget *widget)
Definition: qmenu_mac.mm:1779
QHash< QWidget *, QMenuBar * > MenuBarHash
Definition: qmenu_mac.mm:1615
T * data() const
Definition: qpointer.h:79
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
Definition: qicon.cpp:693
bool modal
Definition: qmenu_mac.mm:99
void syncAction(QMacMenuAction *)
Definition: qmenu_mac.mm:1705
void qt_mac_clear_menubar()
Definition: qmenu_mac.mm:2015
void ignore()
Clears the accept flag parameter of the event object, the equivalent of calling setAccepted(false).
Definition: qcoreevent.h:310
bool italic() const
Returns true if the style() of the font is not QFont::StyleNormal.
Definition: qfont.h:355
int pointSize() const
Returns the point size of the font.
Definition: qfont.cpp:981
OSStatus qt_mac_menu_event(EventHandlerCallRef er, EventRef event, void *)
Definition: qmenu_mac.mm:397
static QHash< OSMenuRef, QMenuMergeList * > mergeMenuItemsHash
Definition: qmenu_p.h:335
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
QSize sizeHint
the recommended size for the widget
Definition: qwidget.h:195
struct OpaqueEventHandlerCallRef * EventHandlerCallRef
QWidget * mac_keyboard_grabber
Definition: qwidget_mac.mm:157
Qt::WindowType windowType() const
Returns the window type of this widget.
Definition: qwidget.h:937
bool qt_mac_activate_action(MenuRef menu, uint command, QAction::ActionEvent action_e, bool by_accel)
Definition: qmenu_mac.mm:209
QPointer< QAction > action
Definition: qmenu_p.h:108
void addAction(QAction *, QMacMenuAction *=0, QMenuPrivate *qmenu=0)
Definition: qmenu_mac.mm:1042
QActionGroup * actionGroup() const
Returns the action group for this action.
Definition: qaction.cpp:747
HIViewRef OSViewRef
static bool testAttribute(Qt::ApplicationAttribute attribute)
Returns true if attribute attribute is set; otherwise returns false.
QString & remove(int i, int len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition: qstring.cpp:1867
void setMacMenuEnabled(bool enable=true)
Definition: qmenu_mac.mm:1574
OSMenuRef macMenu()
Definition: qmenu_mac.mm:1847
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition: qstring.cpp:3796
bool qt_sendSpontaneousEvent(QObject *, QEvent *)
static const KeyPair *const end
OSMenuRef macMenu(OSMenuRef merge)
Definition: qmenu_mac.mm:1529
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
quint32 macFontID() const
Returns an ATSUFontID.
Definition: qfont_mac.cpp:101
void qAddPostRoutine(QtCleanUpFunction ptr)
Adds a global routine that will be called from the QApplication destructor.
uchar merged
Definition: qmenu_p.h:107
bool isExclusive() const
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QChar toLower() const
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1239
static OSStatus qt_mac_widget_in_menu_eventHandler(EventHandlerCallRef er, EventRef event, void *)
Definition: qmenu_mac.mm:312
static uint qt_mac_menu_static_cmd_id
Definition: qmenu_mac.mm:81
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
#define enabled
The QAction class provides an abstract user interface action that can be inserted into widgets...
Definition: qaction.h:64
struct QMenuPrivate::QMacMenuPrivate * mac_menu
int qt_mac_menus_open_count
Definition: qmenu_mac.mm:76
QList< QMenuMergeItem > QMenuMergeList
Definition: qmenu_p.h:123
void qt_event_request_menubarupdate()
#define text
Definition: qobjectdefs.h:80
OSViewRef qt_mac_hiview_for(const QWidget *w)
static QMenuBar * fallback
Definition: qmenu_mac.mm:1617
struct OpaqueIconRef * IconRef
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
static bool qt_mac_auto_apple_menu(MenuCommand cmd)
Definition: qmenu_mac.mm:563
QMultiHash< OSMenuRef, EventHandlerRef > EventHandlerHash
Definition: qmenu_mac.mm:302
void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bool on)
Definition: qmenu_mac.mm:652
int removeAll(const T &t)
Removes all occurrences of value in the list and returns the number of entries removed.
Definition: qlist.h:770
void hovered(QAction *action)
This signal is emitted when a menu action is highlighted; action is the action that caused the event ...
static void qt_mac_create_menu_event_handler()
Definition: qmenu_mac.mm:534
void removeAt(int i)
Removes the item at index position i.
Definition: qlist.h:480