7#include <qpa/qplatformtheme.h>
17#include <QtGui/private/qcoregraphics_p.h>
18#include <QtCore/qregularexpression.h>
19#include <QtCore/private/qcore_mac_p.h>
20#include <QtGui/private/qapplekeymapper_p.h>
22#include <QtCore/QDebug>
43 if (translated != menuString) {
59 m_parentEnabled(true),
70 if (m_menu && m_menu->menuParent() ==
this)
71 m_menu->setMenuParent(
nullptr);
73 m_native.hidden = YES;
75 if (m_menu && m_menu->attachedItem() == m_native)
76 m_menu->setAttachedItem(nil);
98 bool setAttached =
false;
99 if ([m_native.menu isKindOfClass:[
QCocoaNSMenu class]]) {
100 auto parentMenu =
static_cast<QCocoaNSMenu *
>(m_native.menu);
101 setAttached = parentMenu.platformMenu && parentMenu.platformMenu->isAboutToShow();
104 if (m_menu && m_menu->menuParent() ==
this) {
105 m_menu->setMenuParent(
nullptr);
107 m_menu->propagateEnabledState(
true);
108 if (m_native && m_menu->attachedItem() == m_native)
109 m_menu->setAttachedItem(nil);
115 m_menu->setMenuParent(
this);
116 m_menu->propagateEnabledState(
isEnabled());
118 m_menu->setAttachedItem(m_native);
145 m_textSynced =
false;
149#ifndef QT_NO_SHORTCUT
158 m_checked = isChecked;
166 m_menu->propagateEnabledState(
isEnabled());
172 NSView *itemView = (NSView *)
item;
173 if (m_itemView == itemView)
176 m_itemView = [itemView retain];
177 m_itemView.autoresizesSubviews = YES;
178 m_itemView.autoresizingMask = NSViewWidthSizable;
179 m_itemView.hidden = NO;
180 m_itemView.needsDisplay = YES;
185 QString itemCaption(captionWithPossibleMnemonic);
188 static const std::tuple<QPlatformMenuItem::MenuRole, std::vector<std::tuple<Qt::MatchFlags, const char *>>> roleMap[] = {
217 auto match = [](
const QString &caption,
const QString &itemCaption, Qt::MatchFlags matchFlags) {
228 for (
const auto &[role, captions] : roleMap) {
229 for (
const auto &[matchFlags, caption] : captions) {
231 if (
match(caption, itemCaption, matchFlags))
252 if (m_isSeparator != m_native.separatorItem) {
255 m_native = [[
QCocoaNSMenuItem separatorItemWithPlatformMenuItem:
this] retain];
260 if ((m_role !=
NoRole && !m_textSynced) || m_merged) {
266 while (
depth < 3 &&
p && !(menubar = qobject_cast<QCocoaMenuBar *>(
p))) {
269 p = menuObject ? menuObject->
menuParent() :
nullptr;
272 if (menubar &&
depth < 3)
279 NSMenuItem *mergeItem = nil;
283 mergeItem = [
loader aboutMenuItem];
286 mergeItem = [
loader aboutQtMenuItem];
289 mergeItem = [
loader preferencesMenuItem];
292 mergeItem = [
loader appSpecificMenuItem:
this];
295 mergeItem = [
loader quitMenuItem];
306 m_textSynced =
false;
319 m_native = mergeItem;
320 if (
auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(m_native))
321 nativeItem.platformMenuItem =
this;
322 }
else if (m_merged) {
328 }
else if (!m_text.
isEmpty()) {
334 m_native.title = m_text.toNSString();
339 m_native.hidden = !m_isVisible;
340 m_native.view = m_itemView;
343#ifndef QT_NO_SHORTCUT
347 if (accel.
count() > 1)
353#ifndef QT_NO_SHORTCUT
354 if (accel.
count() == 1) {
355 auto key = accel[0].key();
356 auto modifiers = accel[0].keyboardModifiers();
358 QChar cocoaKey = QAppleKeyMapper::toCocoaKey(
key);
363 if (cocoaKey.
unicode() == NSDeleteFunctionKey)
364 cocoaKey =
QChar(NSDeleteCharacter);
366 m_native.keyEquivalent =
QStringView(&cocoaKey, 1).toNSString();
367 m_native.keyEquivalentModifierMask = QAppleKeyMapper::toCocoaModifiers(
modifiers);
371 m_native.keyEquivalent =
@"";
372 m_native.keyEquivalentModifierMask = NSEventModifierFlagCommand;
375 m_native.image = [NSImage imageFromQIcon:m_icon withSize:m_iconSize];
377 m_native.state = m_checked ? NSControlStateValueOn : NSControlStateValueOff;
381QString QCocoaMenuItem::mergeText()
384 if (m_native == [
loader aboutMenuItem]) {
386 }
else if (m_native== [
loader aboutQtMenuItem]) {
387 if (m_text ==
QString(
"About Qt"))
391 }
else if (m_native == [
loader preferencesMenuItem]) {
393 }
else if (m_native == [
loader quitMenuItem]) {
401#ifndef QT_NO_SHORTCUT
405 if (m_native == [
loader preferencesMenuItem])
407 else if (m_native == [
loader quitMenuItem])
419 qCWarning(lcQpaMenus) <<
"Trying to sync non-merged" <<
this;
423 m_native.hidden = !m_isVisible;
428 if (m_parentEnabled !=
enabled) {
431 m_menu->propagateEnabledState(
isEnabled());
440 return m_detectedRole;
450 if (m_native.separatorItem)
464 roleAction =
@selector(
cut:);
467 roleAction =
@selector(
copy:);
470 roleAction =
@selector(
paste:);
486 roleAction =
@selector(submenuAction:);
488 roleAction =
@selector(qt_itemFired:);
492 m_native.action = roleAction;
493 m_native.target = nil;
QChar toLower() const noexcept
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
constexpr char16_t unicode() const noexcept
Returns the numeric Unicode value of the QChar.
constexpr bool isNull() const noexcept
Returns true if the character is the Unicode character 0x0000 ('\0'); otherwise returns false.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
The QIcon class provides scalable icons in different modes and states.
The QKeySequence class encapsulates a key sequence as used by shortcuts.
int count() const
Returns the number of keys in the key sequence.
QString toString(SequenceFormat format=PortableText) const
\inmodule QtCore \reentrant
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
EGLImageKHR int int EGLuint64KHR * modifiers
Combined button and popup list for selecting options.
static jboolean cut(JNIEnv *, jobject)
static jboolean copy(JNIEnv *, jobject)
static jboolean paste(JNIEnv *, jobject)
static jboolean selectAll(JNIEnv *, jobject)
QString qt_mac_applicationName()
static bool isSeparator(char c)
#define qCWarning(category,...)
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei const GLuint GLboolean enabled
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
#define QT_TRANSLATE_NOOP(scope, x)