Cocoa Menus: Clean up code

In this edition:

  * Use Objective-C properties where appropriate.
  * Use recently introduced qt_objc_cast().
  * Remove uses of foreach.
  * Update copyright headers.

Change-Id: I2a07a7b6cab27b833e4deaeedf9563463ff55914
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
bb10
Gabriel de Dietrich 2018-04-20 11:30:35 -07:00
parent b2a282d7c7
commit 25d5c8fe5d
13 changed files with 132 additions and 136 deletions

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -52,13 +52,13 @@ QString msgAboutQt()
static const char *application_menu_strings[] =
{
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1")
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1")
};
QString qt_mac_applicationmenu_string(int type)

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -46,13 +46,13 @@
QT_BEGIN_NAMESPACE
enum {
ServicesAppMenuItem = 0,
AboutAppMenuItem = 0,
PreferencesAppMenuItem,
ServicesAppMenuItem,
HideAppMenuItem,
HideOthersAppMenuItem,
ShowAllAppMenuItem,
PreferencesAppMenuItem,
QuitAppMenuItem,
AboutAppMenuItem
QuitAppMenuItem
};

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**

View File

@ -1,5 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@ -67,7 +68,7 @@ QCocoaMenu::QCocoaMenu() :
QCocoaMenu::~QCocoaMenu()
{
foreach (QCocoaMenuItem *item, m_menuItems) {
for (auto *item : qAsConst(m_menuItems)) {
if (item->menuParent() == this)
item->setMenuParent(nullptr);
}
@ -79,7 +80,7 @@ void QCocoaMenu::setText(const QString &text)
{
QMacAutoReleasePool pool;
QString stripped = qt_mac_removeAmpersandEscapes(text);
[m_nativeMenu setTitle:stripped.toNSString()];
m_nativeMenu.title = stripped.toNSString();
}
void QCocoaMenu::setMinimumWidth(int width)
@ -194,11 +195,11 @@ void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
m_menuItems.removeOne(cocoaItem);
if (!cocoaItem->isMerged()) {
if (m_nativeMenu != [cocoaItem->nsItem() menu]) {
if (m_nativeMenu != cocoaItem->nsItem().menu) {
qWarning("Item to remove does not belong to this menu");
return;
}
[m_nativeMenu removeItem: cocoaItem->nsItem()];
[m_nativeMenu removeItem:cocoaItem->nsItem()];
}
}
@ -247,8 +248,8 @@ void QCocoaMenu::syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUp
// native item was changed for some reason
if (oldItem) {
if (wasMerged) {
[oldItem setEnabled:NO];
[oldItem setHidden:YES];
oldItem.enabled = NO;
oldItem.hidden = YES;
} else {
[m_nativeMenu removeItem:oldItem];
}
@ -278,29 +279,27 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable)
bool previousIsSeparator = true; // setting to true kills all the separators placed at the top.
NSMenuItem *previousItem = nil;
for (NSMenuItem *item in [m_nativeMenu itemArray]) {
if ([item isSeparatorItem]) {
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]);
if (cocoaItem)
for (NSMenuItem *item in m_nativeMenu.itemArray) {
if (item.separatorItem) {
if (auto *cocoaItem = qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem)
cocoaItem->setVisible(!previousIsSeparator);
[item setHidden:previousIsSeparator];
item.hidden = previousIsSeparator;
}
if (![item isHidden]) {
if (!item.hidden) {
previousItem = item;
previousIsSeparator = ([previousItem isSeparatorItem]);
previousIsSeparator = previousItem.separatorItem;
}
}
// We now need to check the final item since we don't want any separators at the end of the list.
if (previousItem && previousIsSeparator) {
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([previousItem tag]);
if (cocoaItem)
if (auto *cocoaItem = qt_objc_cast<QCocoaNSMenuItem *>(previousItem).platformMenuItem)
cocoaItem->setVisible(false);
[previousItem setHidden:YES];
previousItem.hidden = YES;
}
} else {
foreach (QCocoaMenuItem *item, m_menuItems) {
for (auto *item : qAsConst(m_menuItems)) {
if (!item->isSeparator())
continue;
@ -322,7 +321,7 @@ void QCocoaMenu::setEnabled(bool enabled)
bool QCocoaMenu::isEnabled() const
{
return m_attachedItem ? [m_attachedItem isEnabled] : m_enabled && m_parentEnabled;
return m_attachedItem ? m_attachedItem.enabled : m_enabled && m_parentEnabled;
}
void QCocoaMenu::setVisible(bool visible)
@ -358,9 +357,9 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
// respect the menu's minimum width.
NSPopUpButtonCell *popupCell = [[[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]
autorelease];
[popupCell setAltersStateOfSelectedItem:NO];
[popupCell setTransparent:YES];
[popupCell setMenu:m_nativeMenu];
popupCell.altersStateOfSelectedItem = NO;
popupCell.transparent = YES;
popupCell.menu = m_nativeMenu;
[popupCell selectItem:nsItem];
QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(screen->handle());
@ -428,7 +427,7 @@ QPlatformMenuItem *QCocoaMenu::menuItemAt(int position) const
QPlatformMenuItem *QCocoaMenu::menuItemForTag(quintptr tag) const
{
foreach (QCocoaMenuItem *item, m_menuItems) {
for (auto *item : qAsConst(m_menuItems)) {
if (item->tag() == tag)
return item;
}
@ -444,7 +443,7 @@ QList<QCocoaMenuItem *> QCocoaMenu::items() const
QList<QCocoaMenuItem *> QCocoaMenu::merged() const
{
QList<QCocoaMenuItem *> result;
foreach (QCocoaMenuItem *item, m_menuItems) {
for (auto *item : qAsConst(m_menuItems)) {
if (item->menu()) { // recurse into submenus
result.append(item->menu()->merged());
continue;
@ -465,7 +464,7 @@ void QCocoaMenu::propagateEnabledState(bool enabled)
if (!m_enabled && enabled) // Some ancestor was enabled, but this menu is not
return;
foreach (QCocoaMenuItem *item, m_menuItems) {
for (auto *item : qAsConst(m_menuItems)) {
if (QCocoaMenu *menu = item->menu())
menu->propagateEnabledState(enabled);
else

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@ -68,7 +68,7 @@ public:
static void updateMenuBarImmediately();
QList<QCocoaMenuItem*> merged() const;
NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole r);
NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole role);
QCocoaWindow *cocoaWindow() const;
void syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate);

View File

@ -1,5 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@ -67,7 +68,7 @@ QCocoaMenuBar::~QCocoaMenuBar()
#ifdef QT_COCOA_ENABLE_MENU_DEBUG
qDebug() << "~QCocoaMenuBar" << this;
#endif
foreach (QCocoaMenu *menu, m_menus) {
for (auto menu : qAsConst(m_menus)) {
if (!menu)
continue;
NSMenuItem *item = nativeItemForMenu(menu);
@ -198,8 +199,8 @@ void QCocoaMenuBar::syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate)
// If the NSMenu has no visble items, or only separators, we should hide it
// on the menubar. This can happen after syncing the menu items since they
// can be moved to other menus.
for (NSMenuItem *item in [cocoaMenu->nsMenu() itemArray])
if (![item isSeparatorItem] && ![item isHidden]) {
for (NSMenuItem *item in cocoaMenu->nsMenu().itemArray)
if (!item.separatorItem && !item.hidden) {
shouldHide = NO;
break;
}
@ -245,17 +246,17 @@ QCocoaWindow *QCocoaMenuBar::findWindowForMenubar()
if (qApp->focusWindow())
return static_cast<QCocoaWindow*>(qApp->focusWindow()->handle());
return NULL;
return nullptr;
}
QCocoaMenuBar *QCocoaMenuBar::findGlobalMenubar()
{
foreach (QCocoaMenuBar *mb, static_menubars) {
if (mb->m_window.isNull())
return mb;
for (auto *menubar : qAsConst(static_menubars)) {
if (menubar->m_window.isNull())
return menubar;
}
return NULL;
return nullptr;
}
void QCocoaMenuBar::updateMenuBarImmediately()
@ -292,7 +293,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
#endif
bool disableForModal = mb->shouldDisable(cw);
foreach (QCocoaMenu *menu, mb->m_menus) {
for (auto menu : qAsConst(mb->m_menus)) {
if (!menu)
continue;
NSMenuItem *item = mb->nativeItemForMenu(menu);
@ -307,16 +308,16 @@ void QCocoaMenuBar::updateMenuBarImmediately()
[loader ensureAppMenuInMenu:mb->nsMenu()];
NSMutableSet *mergedItems = [[NSMutableSet setWithCapacity:mb->merged().count()] retain];
foreach (QCocoaMenuItem *m, mb->merged()) {
[mergedItems addObject:m->nsItem()];
m->syncMerged();
for (auto mergedItem : mb->merged()) {
[mergedItems addObject:mergedItem->nsItem()];
mergedItem->syncMerged();
}
// hide+disable all mergeable items we're not currently using
for (NSMenuItem *mergeable in [loader mergeable]) {
if (![mergedItems containsObject:mergeable]) {
[mergeable setHidden:YES];
[mergeable setEnabled:NO];
mergeable.hidden = YES;
mergeable.enabled = NO;
}
}
@ -328,7 +329,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
QList<QCocoaMenuItem*> QCocoaMenuBar::merged() const
{
QList<QCocoaMenuItem*> r;
foreach (QCocoaMenu* menu, m_menus)
for (auto menu : qAsConst(m_menus))
r.append(menu->merged());
return r;
@ -348,11 +349,11 @@ bool QCocoaMenuBar::shouldDisable(QCocoaWindow *active) const
// When there is an application modal window on screen, the entries of
// the menubar should be disabled. The exception in Qt is that if the
// modal window is the only window on screen, then we enable the menu bar.
foreach (QWindow *w, topWindows) {
if (w->isVisible() && w->modality() == Qt::ApplicationModal) {
for (auto *window : qAsConst(topWindows)) {
if (window->isVisible() && window->modality() == Qt::ApplicationModal) {
// check for other visible windows
foreach (QWindow *other, topWindows) {
if ((w != other) && (other->isVisible())) {
for (auto *other : qAsConst(topWindows)) {
if ((window != other) && (other->isVisible())) {
// INVARIANT: we found another visible window
// on screen other than our modalWidget. We therefore
// disable the menu bar to follow normal modality logic:
@ -372,21 +373,21 @@ bool QCocoaMenuBar::shouldDisable(QCocoaWindow *active) const
QPlatformMenu *QCocoaMenuBar::menuForTag(quintptr tag) const
{
foreach (QCocoaMenu *menu, m_menus) {
for (auto menu : qAsConst(m_menus))
if (menu->tag() == tag)
return menu;
}
return nullptr;
}
NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole r)
NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole role)
{
foreach (QCocoaMenu *m, m_menus)
foreach (QCocoaMenuItem *i, m->items())
if (i->effectiveRole() == r)
return i->nsItem();
return nullptr;
for (auto menu : qAsConst(m_menus))
for (auto *item : menu->items())
if (item->effectiveRole() == role)
return item->nsItem();
return nil;
}
QCocoaWindow *QCocoaMenuBar::cocoaWindow() const

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**

View File

@ -1,5 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@ -115,7 +116,7 @@ QCocoaMenuItem::~QCocoaMenuItem()
if (m_menu && m_menu->menuParent() == this)
m_menu->setMenuParent(nullptr);
if (m_merged) {
[m_native setHidden:YES];
m_native.hidden = YES;
} else {
if (m_menu && m_menu->attachedItem() == m_native)
m_menu->setAttachedItem(nil);
@ -211,10 +212,10 @@ void QCocoaMenuItem::setNativeContents(WId item)
return;
[m_itemView release];
m_itemView = [itemView retain];
[m_itemView setAutoresizesSubviews:YES];
[m_itemView setAutoresizingMask:NSViewWidthSizable];
[m_itemView setHidden:NO];
[m_itemView setNeedsDisplay:YES];
m_itemView.autoresizesSubviews = YES;
m_itemView.autoresizingMask = NSViewWidthSizable;
m_itemView.hidden = NO;
m_itemView.needsDisplay = YES;
}
NSMenuItem *QCocoaMenuItem::sync()
@ -313,8 +314,8 @@ NSMenuItem *QCocoaMenuItem::sync()
resolveTargetAction();
[m_native setHidden: !m_isVisible];
[m_native setView:m_itemView];
m_native.hidden = !m_isVisible;
m_native.view = m_itemView;
QString text = mergeText();
#ifndef QT_NO_SHORTCUT
@ -334,34 +335,33 @@ NSMenuItem *QCocoaMenuItem::sync()
if (customMenuFont) {
NSAttributedString *str = [[[NSAttributedString alloc] initWithString:finalString.toNSString()
attributes:@{NSFontAttributeName: customMenuFont}] autorelease];
[m_native setAttributedTitle:str];
m_native.attributedTitle = str;
useAttributedTitle = true;
}
}
if (!useAttributedTitle) {
[m_native setTitle:finalString.toNSString()];
}
if (!useAttributedTitle)
m_native.title = finalString.toNSString();
#ifndef QT_NO_SHORTCUT
if (accel.count() == 1) {
[m_native setKeyEquivalent:keySequenceToKeyEqivalent(accel)];
[m_native setKeyEquivalentModifierMask:keySequenceModifierMask(accel)];
m_native.keyEquivalent = keySequenceToKeyEqivalent(accel);
m_native.keyEquivalentModifierMask = keySequenceModifierMask(accel);
} else
#endif
{
[m_native setKeyEquivalent:@""];
[m_native setKeyEquivalentModifierMask:NSCommandKeyMask];
m_native.keyEquivalent = @"";
m_native.keyEquivalentModifierMask = NSCommandKeyMask;
}
NSImage *img = nil;
if (!m_icon.isNull()) {
img = qt_mac_create_nsimage(m_icon, m_iconSize);
[img setSize:NSMakeSize(m_iconSize, m_iconSize)];
img.size = CGSizeMake(m_iconSize, m_iconSize);
}
[m_native setImage:img];
m_native.image = img;
[img release];
[m_native setState:m_checked ? NSOnState : NSOffState];
m_native.state = m_checked ? NSOnState : NSOffState;
return m_native;
}
@ -406,8 +406,8 @@ void QCocoaMenuItem::syncMerged()
qWarning("Trying to sync a non-merged item");
return;
}
[m_native setTag:reinterpret_cast<NSInteger>(this)];
[m_native setHidden: !m_isVisible];
m_native.hidden = !m_isVisible;
}
void QCocoaMenuItem::setParentEnabled(bool enabled)

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -206,18 +206,18 @@
// windows with different menu bars), we never recreate this menu, but
// instead pull it out the current menu bar and place into the new one:
NSMenu *mainMenu = [NSApp mainMenu];
if ([NSApp mainMenu] == menu)
if (mainMenu == menu)
return; // nothing to do (menu is the current menu bar)!
#ifndef QT_NAMESPACE
Q_ASSERT(mainMenu);
#endif
// Grab the app menu out of the current menu.
int numItems = [mainMenu numberOfItems];
const int numItems = mainMenu.numberOfItems;
NSMenuItem *oldAppMenuItem = nil;
for (int i = 0; i < numItems; ++i) {
NSMenuItem *item = [mainMenu itemAtIndex:i];
if ([item submenu] == appMenu) {
if (item.submenu == appMenu) {
oldAppMenuItem = item;
[oldAppMenuItem retain];
[mainMenu removeItemAtIndex:i];
@ -226,11 +226,11 @@
}
if (oldAppMenuItem) {
[oldAppMenuItem setSubmenu:nil];
oldAppMenuItem.submenu = nil;
[oldAppMenuItem release];
NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple"
action:nil keyEquivalent:@""];
[appMenuItem setSubmenu:appMenu];
action:nil keyEquivalent:@""];
appMenuItem.submenu = appMenu;
[menu insertItem:appMenuItem atIndex:0];
}
}
@ -274,8 +274,7 @@
{
// No reason to create the item if it already exists.
for (NSMenuItem *item in appMenu.itemArray)
if ([item isMemberOfClass:[QCocoaNSMenuItem class]]
&& static_cast<QCocoaNSMenuItem *>(item).platformMenuItem == platformItem)
if (qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem == platformItem)
return [[item retain] autorelease];
// Create an App-Specific menu item, insert it into the menu and return
@ -320,13 +319,13 @@
- (void)qtTranslateApplicationMenu
{
#ifndef QT_NO_TRANSLATION
[servicesItem setTitle:qt_mac_applicationmenu_string(ServicesAppMenuItem).toNSString()];
[hideItem setTitle:qt_mac_applicationmenu_string(HideAppMenuItem).arg(qt_mac_applicationName()).toNSString()];
[hideAllOthersItem setTitle:qt_mac_applicationmenu_string(HideOthersAppMenuItem).toNSString()];
[showAllItem setTitle:qt_mac_applicationmenu_string(ShowAllAppMenuItem).toNSString()];
[preferencesItem setTitle:qt_mac_applicationmenu_string(PreferencesAppMenuItem).toNSString()];
[quitItem setTitle:qt_mac_applicationmenu_string(QuitAppMenuItem).arg(qt_mac_applicationName()).toNSString()];
[aboutItem setTitle:qt_mac_applicationmenu_string(AboutAppMenuItem).arg(qt_mac_applicationName()).toNSString()];
aboutItem.title = qt_mac_applicationmenu_string(AboutAppMenuItem).arg(qt_mac_applicationName()).toNSString();
preferencesItem.title = qt_mac_applicationmenu_string(PreferencesAppMenuItem).toNSString();
servicesItem.title = qt_mac_applicationmenu_string(ServicesAppMenuItem).toNSString();
hideItem.title = qt_mac_applicationmenu_string(HideAppMenuItem).arg(qt_mac_applicationName()).toNSString();
hideAllOthersItem.title = qt_mac_applicationmenu_string(HideOthersAppMenuItem).toNSString();
showAllItem.title = qt_mac_applicationmenu_string(ShowAllAppMenuItem).toNSString();
quitItem.title = qt_mac_applicationmenu_string(QuitAppMenuItem).arg(qt_mac_applicationName()).toNSString();
#endif
}

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -44,17 +44,15 @@
#include "qcocoawindow.h"
#import "qnsview.h"
#include <QtCore/qmetaobject.h>
#include <QtCore/private/qthread_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qcoreevent.h>
static NSString *qt_mac_removePrivateUnicode(NSString* string)
static NSString *qt_mac_removePrivateUnicode(NSString *string)
{
int len = [string length];
if (len) {
QVarLengthArray <unichar, 10> characters(len);
if (const int len = string.length) {
QVarLengthArray<unichar, 10> characters(len);
bool changed = false;
for (int i = 0; i<len; i++) {
for (int i = 0; i < len; i++) {
characters[i] = [string characterAtIndex:i];
// check if they belong to key codes in private unicode range
// currently we need to handle only the NSDeleteFunctionKey
@ -100,9 +98,8 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
+ (instancetype)separatorItemWithPlatformMenuItem:(QCocoaMenuItem *)menuItem
{
// Safe because +[NSMenuItem separatorItem] invokes [[self alloc] init]
auto *item = static_cast<QCocoaNSMenuItem *>([self separatorItem]);
Q_ASSERT_X([item isMemberOfClass:[QCocoaNSMenuItem class]],
qPrintable(__FUNCTION__),
auto *item = qt_objc_cast<QCocoaNSMenuItem *>([self separatorItem]);
Q_ASSERT_X(item, qPrintable(__FUNCTION__),
"Did +[NSMenuItem separatorItem] not invoke [[self alloc] init]?");
if (item)
item.platformMenuItem = menuItem;
@ -136,7 +133,8 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
@end
#define CHECK_MENU_CLASS(menu) Q_ASSERT([menu isMemberOfClass:[QCocoaNSMenu class]])
#define CHECK_MENU_CLASS(menu) Q_ASSERT_X([menu isMemberOfClass:[QCocoaNSMenu class]], \
__FUNCTION__, "Menu is not a QCocoaNSMenu")
@implementation QCocoaNSMenuDelegate
@ -172,10 +170,9 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
if (!platformMenu)
return YES;
if ([item isMemberOfClass:[QCocoaNSMenuItem class]]) {
auto *menuItem = static_cast<QCocoaNSMenuItem *>(item).platformMenuItem;
if (platformMenu->items().contains(menuItem)) {
if (QCocoaMenu *itemSubmenu = menuItem->menu())
if (auto *platformItem = qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem) {
if (platformMenu->items().contains(platformItem)) {
if (auto *itemSubmenu = platformItem->menu())
itemSubmenu->setAttachedItem(item);
}
}
@ -186,10 +183,8 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
- (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item
{
CHECK_MENU_CLASS(menu);
if ([item isMemberOfClass:[QCocoaNSMenuItem class]]) {
if (auto *platformItem = static_cast<QCocoaNSMenuItem *>(item).platformMenuItem)
emit platformItem->hovered();
}
if (auto *platformItem = qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem)
emit platformItem->hovered();
}
- (void)menuWillOpen:(NSMenu *)menu
@ -251,13 +246,13 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
if (object) {
QChar ch;
int keyCode;
ulong nativeModifiers = [event modifierFlags];
Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers];
NSString *charactersIgnoringModifiers = [event charactersIgnoringModifiers];
NSString *characters = [event characters];
ulong nativeModifiers = event.modifierFlags;
Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers:nativeModifiers];
NSString *charactersIgnoringModifiers = event.charactersIgnoringModifiers;
NSString *characters = event.characters;
if ([charactersIgnoringModifiers length] > 0) { // convert the first character into a key code
if ((modifiers & Qt::ControlModifier) && ([characters length] != 0)) {
if (charactersIgnoringModifiers.length > 0) { // convert the first character into a key code
if ((modifiers & Qt::ControlModifier) && characters.length > 0) {
ch = QChar([characters characterAtIndex:0]);
} else {
ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
@ -274,7 +269,7 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
accel_ev.ignore();
QCoreApplication::sendEvent(object, &accel_ev);
if (accel_ev.isAccepted()) {
[[NSApp keyWindow] sendEvent: event];
[[NSApp keyWindow] sendEvent:event];
*target = nil;
*action = nil;
return YES;

View File

@ -60,10 +60,11 @@ static bool selectorIsCutCopyPaste(SEL selector)
- (BOOL)validateMenuItem:(NSMenuItem*)item
{
if (![item isMemberOfClass:[QCocoaNSMenuItem class]])
auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(item);
if (!nativeItem)
return item.enabled; // FIXME Test with with Qt as plugin or embedded QWindow.
auto *platformItem = static_cast<QCocoaNSMenuItem *>(item).platformMenuItem;
auto *platformItem = nativeItem.platformMenuItem;
if (!platformItem)
return NO;
@ -100,8 +101,9 @@ static bool selectorIsCutCopyPaste(SEL selector)
- (void)qt_itemFired:(QCocoaNSMenuItem *)item
{
Q_ASSERT([item isMemberOfClass:[QCocoaNSMenuItem class]]);
auto *platformItem = static_cast<QCocoaNSMenuItem *>(item).platformMenuItem;
auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(item);
Q_ASSERT_X(nativeItem, qPrintable(__FUNCTION__), "Triggered menu item is not a QCocoaNSMenuItem.");
auto *platformItem = nativeItem.platformMenuItem;
// Menu-holding items also get a target to play nicely
// with NSMenuValidation but should not trigger.
if (!platformItem || platformItem->menu())
@ -129,8 +131,8 @@ static bool selectorIsCutCopyPaste(SEL selector)
if (selectorIsCutCopyPaste(invocation.selector)) {
NSObject *sender;
[invocation getArgument:&sender atIndex:2];
if ([sender isMemberOfClass:[QCocoaNSMenuItem class]]) {
[self qt_itemFired:static_cast<QCocoaNSMenuItem *>(sender)];
if (auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(sender)) {
[self qt_itemFired:nativeItem];
return;
}
}