aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp86
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p.h8
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p_p.h10
-rw-r--r--tests/auto/controls/data/tst_abstractbutton.qml34
4 files changed, 136 insertions, 2 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index 23b73200..e66a33e5 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -39,9 +39,12 @@
#include "qquickbuttongroup_p.h"
#include "qquickaction_p.h"
#include "qquickaction_p_p.h"
+#include "qquickshortcutcontext_p_p.h"
#include <QtGui/qstylehints.h>
#include <QtGui/qguiapplication.h>
+#include <QtGui/private/qshortcutmap_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtQuick/private/qquickevents_p_p.h>
#include <QtQml/qqmllist.h>
@@ -176,6 +179,9 @@ QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate()
holdTimer(0),
delayTimer(0),
repeatTimer(0),
+#if QT_CONFIG(shortcut)
+ shortcutId(0),
+#endif
pressButtons(Qt::NoButton),
indicator(nullptr),
group(nullptr),
@@ -303,6 +309,30 @@ void QQuickAbstractButtonPrivate::stopPressRepeat()
}
}
+#if QT_CONFIG(shortcut)
+void QQuickAbstractButtonPrivate::grabShortcut()
+{
+ Q_Q(QQuickAbstractButton);
+ if (shortcut.isEmpty())
+ return;
+
+ shortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(q, shortcut, Qt::WindowShortcut, QQuickShortcutContext::matcher);
+
+ if (!q->isEnabled())
+ QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(false, shortcutId, q);
+}
+
+void QQuickAbstractButtonPrivate::ungrabShortcut()
+{
+ Q_Q(QQuickAbstractButton);
+ if (!shortcutId)
+ return;
+
+ QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(shortcutId, q);
+ shortcutId = 0;
+}
+#endif
+
void QQuickAbstractButtonPrivate::click()
{
Q_Q(QQuickAbstractButton);
@@ -424,8 +454,12 @@ void QQuickAbstractButton::setText(const QString &text)
if (d->text == text)
return;
- d->text = text;
- setAccessibleName(text);
+#if QT_CONFIG(shortcut)
+ setShortcut(QKeySequence::mnemonic(text));
+#endif
+
+ d->text = QPlatformTheme::removeMnemonics(text); // ### TODO: visualize mnemonics
+ setAccessibleName(d->text);
buttonChange(ButtonTextChange);
emit textChanged();
}
@@ -775,6 +809,25 @@ void QQuickAbstractButton::setAction(QQuickAction *action)
emit actionChanged();
}
+#if QT_CONFIG(shortcut)
+QKeySequence QQuickAbstractButton::shortcut() const
+{
+ Q_D(const QQuickAbstractButton);
+ return d->shortcut;
+}
+
+void QQuickAbstractButton::setShortcut(const QKeySequence &shortcut)
+{
+ Q_D(QQuickAbstractButton);
+ if (d->shortcut == shortcut)
+ return;
+
+ d->ungrabShortcut();
+ d->shortcut = shortcut;
+ d->grabShortcut();
+}
+#endif
+
/*!
\qmlmethod void QtQuick.Controls::AbstractButton::toggle()
@@ -786,6 +839,21 @@ void QQuickAbstractButton::toggle()
setChecked(!d->checked);
}
+bool QQuickAbstractButton::event(QEvent *event)
+{
+ Q_D(QQuickAbstractButton);
+#if QT_CONFIG(shortcut)
+ if (event->type() == QEvent::Shortcut) {
+ QShortcutEvent *se = static_cast<QShortcutEvent *>(event);
+ if (se->shortcutId() == d->shortcutId) {
+ d->click();
+ return true;
+ }
+ }
+#endif
+ return QQuickControl::event(event);
+}
+
void QQuickAbstractButton::focusOutEvent(QFocusEvent *event)
{
Q_D(QQuickAbstractButton);
@@ -857,6 +925,20 @@ void QQuickAbstractButton::timerEvent(QTimerEvent *event)
}
}
+void QQuickAbstractButton::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ Q_D(QQuickAbstractButton);
+ QQuickControl::itemChange(change, value);
+#if QT_CONFIG(shortcut)
+ if (change == ItemVisibleHasChanged) {
+ if (value.boolValue)
+ d->grabShortcut();
+ else
+ d->ungrabShortcut();
+ }
+#endif
+}
+
void QQuickAbstractButton::buttonChange(ButtonChange change)
{
Q_D(QQuickAbstractButton);
diff --git a/src/quicktemplates2/qquickabstractbutton_p.h b/src/quicktemplates2/qquickabstractbutton_p.h
index 25827c9f..81384298 100644
--- a/src/quicktemplates2/qquickabstractbutton_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p.h
@@ -116,6 +116,11 @@ public:
QQuickAction *action() const;
void setAction(QQuickAction *action);
+#if QT_CONFIG(shortcut)
+ QKeySequence shortcut() const;
+ void setShortcut(const QKeySequence &shortcut);
+#endif
+
public Q_SLOTS:
void toggle();
@@ -141,6 +146,7 @@ Q_SIGNALS:
protected:
QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent);
+ bool event(QEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
void keyReleaseEvent(QKeyEvent *event) override;
@@ -148,6 +154,8 @@ protected:
void mouseDoubleClickEvent(QMouseEvent *event) override;
void timerEvent(QTimerEvent *event) override;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
+
enum ButtonChange {
ButtonAutoRepeatChange,
ButtonCheckedChange,
diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h
index f1fef5e5..659846e5 100644
--- a/src/quicktemplates2/qquickabstractbutton_p_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p_p.h
@@ -50,6 +50,7 @@
#include <QtQuickTemplates2/private/qquickabstractbutton_p.h>
#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
+#include <QtGui/qkeysequence.h>
QT_BEGIN_NAMESPACE
@@ -81,6 +82,11 @@ public:
void startPressRepeat();
void stopPressRepeat();
+#if QT_CONFIG(shortcut)
+ void grabShortcut();
+ void ungrabShortcut();
+#endif
+
QQuickAbstractButton *findCheckedButton() const;
QList<QQuickAbstractButton *> findExclusiveButtons() const;
@@ -101,6 +107,10 @@ public:
int holdTimer;
int delayTimer;
int repeatTimer;
+#if QT_CONFIG(shortcut)
+ int shortcutId;
+ QKeySequence shortcut;
+#endif
QQuickIcon icon;
QPointF pressPoint;
Qt::MouseButtons pressButtons;
diff --git a/tests/auto/controls/data/tst_abstractbutton.qml b/tests/auto/controls/data/tst_abstractbutton.qml
index a7f4ab8a..c65930be 100644
--- a/tests/auto/controls/data/tst_abstractbutton.qml
+++ b/tests/auto/controls/data/tst_abstractbutton.qml
@@ -289,4 +289,38 @@ TestCase {
compare(buttonSpy.count, data.clicked ? 1 : 0)
compare(actionSpy.count, data.triggered ? 1 : 0)
}
+
+ function test_mnemonic() {
+ if (Qt.platform.os === "osx" || Qt.platform.os === "macos")
+ skip("Mnemonics are not used on macOS")
+
+ var control = createTemporaryObject(button, testCase)
+ verify(control)
+
+ control.text = "&Hello"
+ compare(control.text, "Hello") // ### TODO: visualize mnemonics
+
+ var clickSpy = signalSpy.createObject(control, {target: control, signalName: "clicked"})
+ verify(clickSpy.valid)
+
+ keyClick(Qt.Key_H, Qt.AltModifier)
+ compare(clickSpy.count, 1)
+
+ control.visible = false
+ keyClick(Qt.Key_H, Qt.AltModifier)
+ compare(clickSpy.count, 1)
+
+ control.visible = true
+ keyClick(Qt.Key_H, Qt.AltModifier)
+ compare(clickSpy.count, 2)
+
+ control.text = "Te&st"
+ compare(control.text, "Test") // ### TODO: visualize mnemonics
+
+ keyClick(Qt.Key_H, Qt.AltModifier)
+ compare(clickSpy.count, 2)
+
+ keyClick(Qt.Key_S, Qt.AltModifier)
+ compare(clickSpy.count, 3)
+ }
}