diff options
author | Jake Petroules <jake.petroules@qt.io> | 2017-03-10 16:55:04 -0800 |
---|---|---|
committer | Jake Petroules <jake.petroules@qt.io> | 2017-03-14 05:29:22 +0000 |
commit | c2c3452ba5b4c32d0c2d5df9193bf89986623ab5 (patch) | |
tree | 66b567681989e166bc429f477ae7f13f9c844f75 /src/widgets | |
parent | b6e3fd8ced2ae3629b73b78bf436d1a3ac4bccda (diff) |
Add new API to control whether shortcuts are shown in context menus
Shortcuts are universally not shown on macOS or mobile platforms, making
applications look very obviously out of place.
Windows and GNOME desktop environments almost never use them.
Only KDE appears to do so commonly; default accordingly.
Task-number: QTBUG-49435
Change-Id: Ieac4cee57b15a02be5258f3d07749af6316af62b
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/kernel/qaction.cpp | 42 | ||||
-rw-r--r-- | src/widgets/kernel/qaction.h | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qaction_p.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qlineedit.cpp | 5 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu.cpp | 5 | ||||
-rw-r--r-- | src/widgets/widgets/qwidgettextcontrol.cpp | 5 |
6 files changed, 57 insertions, 4 deletions
diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index 4582a55394..ec7dc34d4d 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -45,6 +45,7 @@ #include "qapplication.h" #include "qevent.h" #include "qlist.h" +#include "qstylehints.h" #include <private/qshortcutmap_p.h> #include <private/qapplication_p.h> #include <private/qmenu_p.h> @@ -75,6 +76,7 @@ static QString qt_strippedText(QString s) QActionPrivate::QActionPrivate() : group(0), enabled(1), forceDisabled(0), visible(1), forceInvisible(0), checkable(0), checked(0), separator(0), fontSet(false), iconVisibleInMenu(-1), + shortcutVisibleInContextMenu(-1), menuRole(QAction::TextHeuristicRole), priority(QAction::NormalPriority) { @@ -1292,6 +1294,46 @@ bool QAction::isIconVisibleInMenu() const return d->iconVisibleInMenu; } +/*! + \property QAction::shortcutVisibleInContextMenu + \brief Whether or not an action should show a shortcut in a context menu + \since 5.10 + + In some applications, it may make sense to have actions with shortcuts in + context menus. If true, the shortcut (if valid) is shown when the action is + shown via a context menu, when it is false, it is not shown. + + The default is to follow whether the Qt::AA_DontShowShortcutsInContextMenus attribute + is set for the application, falling back to the widget style hint. + Explicitly setting this property overrides the presence (or abscence) of the attribute. + + \sa QAction::shortcut, QCoreApplication::setAttribute() +*/ +void QAction::setShortcutVisibleInContextMenu(bool visible) +{ + Q_D(QAction); + if (d->shortcutVisibleInContextMenu == -1 || visible != bool(d->shortcutVisibleInContextMenu)) { + int oldValue = d->shortcutVisibleInContextMenu; + d->shortcutVisibleInContextMenu = visible; + // Only send data changed if we really need to. + if (oldValue != -1 + || visible == !QApplication::instance()->testAttribute(Qt::AA_DontShowShortcutsInContextMenus)) { + d->sendDataChanged(); + } + } +} + +bool QAction::isShortcutVisibleInContextMenu() const +{ + Q_D(const QAction); + if (d->shortcutVisibleInContextMenu == -1) { + if (QApplication::instance()->testAttribute(Qt::AA_DontShowIconsInMenus)) + return false; + return qApp->styleHints()->showShortcutsInContextMenus(); + } + return d->shortcutVisibleInContextMenu; +} + #ifndef QT_NO_DEBUG_STREAM Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QAction *action) { diff --git a/src/widgets/kernel/qaction.h b/src/widgets/kernel/qaction.h index 97948a2457..d211016931 100644 --- a/src/widgets/kernel/qaction.h +++ b/src/widgets/kernel/qaction.h @@ -80,6 +80,7 @@ class Q_WIDGETS_EXPORT QAction : public QObject Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY changed) Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed) Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed) + Q_PROPERTY(bool shortcutVisibleInContextMenu READ isShortcutVisibleInContextMenu WRITE setShortcutVisibleInContextMenu NOTIFY changed) Q_PROPERTY(Priority priority READ priority WRITE setPriority) public: @@ -168,6 +169,8 @@ public: void setIconVisibleInMenu(bool visible); bool isIconVisibleInMenu() const; + void setShortcutVisibleInContextMenu(bool show); + bool isShortcutVisibleInContextMenu() const; QWidget *parentWidget() const; diff --git a/src/widgets/kernel/qaction_p.h b/src/widgets/kernel/qaction_p.h index 8ee71a5ff0..5f4c9a35a3 100644 --- a/src/widgets/kernel/qaction_p.h +++ b/src/widgets/kernel/qaction_p.h @@ -106,6 +106,7 @@ public: uint fontSet : 1; int iconVisibleInMenu : 3; // Only has values -1, 0, and 1 + int shortcutVisibleInContextMenu : 2; // Only has values -1, 0, and 1 QAction::MenuRole menuRole; QAction::Priority priority; diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index fb0ffd6083..419968db75 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -74,7 +74,10 @@ #include "private/qapplication_p.h" #include "private/qshortcutmap_p.h" #include "qkeysequence.h" -#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \ +#define ACCEL_KEY(k) ((qApp->testAttribute(Qt::AA_DontShowIconsInMenus) \ + ? false \ + : qApp->styleHints()->showShortcutsInContextMenus()) \ + && !qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \ QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString()) #else #define ACCEL_KEY(k) QString() diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 2917083415..295fb7d89c 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -332,7 +332,7 @@ void QMenuPrivate::updateActionRects(const QRect &screen) const tabWidth = qMax(int(tabWidth), qfm.width(s.mid(t+1))); s = s.left(t); #ifndef QT_NO_SHORTCUT - } else { + } else if (action->isShortcutVisibleInContextMenu()) { QKeySequence seq = action->shortcut(); if (!seq.isEmpty()) tabWidth = qMax(int(tabWidth), qfm.width(seq.toString(QKeySequence::NativeText))); @@ -1447,7 +1447,8 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) option->icon = action->icon(); QString textAndAccel = action->text(); #ifndef QT_NO_SHORTCUT - if (textAndAccel.indexOf(QLatin1Char('\t')) == -1) { + if (action->isShortcutVisibleInContextMenu() + && textAndAccel.indexOf(QLatin1Char('\t')) == -1) { QKeySequence seq = action->shortcut(); if (!seq.isEmpty()) textAndAccel += QLatin1Char('\t') + seq.toString(QKeySequence::NativeText); diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index f5672bd87a..9aec94d47f 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -85,7 +85,10 @@ #include "private/qapplication_p.h" #include "private/qshortcutmap_p.h" #include <qkeysequence.h> -#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \ +#define ACCEL_KEY(k) ((qApp->testAttribute(Qt::AA_DontShowIconsInMenus) \ + ? false \ + : qApp->styleHints()->showShortcutsInContextMenus()) \ + && !qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \ QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString()) #else |