summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qshortcut.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qshortcut.cpp')
-rw-r--r--src/gui/kernel/qshortcut.cpp279
1 files changed, 188 insertions, 91 deletions
diff --git a/src/gui/kernel/qshortcut.cpp b/src/gui/kernel/qshortcut.cpp
index c4305d5a7f..3f6822cb03 100644
--- a/src/gui/kernel/qshortcut.cpp
+++ b/src/gui/kernel/qshortcut.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qshortcut.h"
#include "qshortcut_p.h"
@@ -132,7 +96,7 @@ QT_BEGIN_NAMESPACE
\sa activated()
*/
-static bool simpleContextMatcher(QObject *object, Qt::ShortcutContext context)
+bool QShortcutPrivate::simpleContextMatcher(QObject *object, Qt::ShortcutContext context)
{
auto guiShortcut = qobject_cast<QShortcut *>(object);
if (QGuiApplication::applicationState() != Qt::ApplicationActive || guiShortcut == nullptr)
@@ -163,15 +127,23 @@ void QShortcutPrivate::redoGrab(QShortcutMap &map)
return;
}
- if (sc_id)
- map.removeShortcut(sc_id, q);
- if (sc_sequence.isEmpty())
+ for (int id : std::as_const(sc_ids))
+ map.removeShortcut(id, q);
+
+ sc_ids.clear();
+ if (sc_sequences.isEmpty())
return;
- sc_id = map.addShortcut(q, sc_sequence, sc_context, contextMatcher());
- if (!sc_enabled)
- map.setShortcutEnabled(false, sc_id, q);
- if (!sc_autorepeat)
- map.setShortcutAutoRepeat(false, sc_id, q);
+ sc_ids.reserve(sc_sequences.size());
+ for (const auto &keySequence : std::as_const(sc_sequences)) {
+ if (keySequence.isEmpty())
+ continue;
+ int id = map.addShortcut(q, keySequence, sc_context, contextMatcher());
+ sc_ids.append(id);
+ if (!sc_enabled)
+ map.setShortcutEnabled(false, id, q);
+ if (!sc_autorepeat)
+ map.setShortcutAutoRepeat(false, id, q);
+ }
}
QShortcutPrivate *QGuiApplicationPrivate::createShortcutPrivate() const
@@ -210,7 +182,34 @@ QShortcut::QShortcut(const QKeySequence &key, QObject *parent,
{
Q_D(QShortcut);
d->sc_context = context;
- d->sc_sequence = key;
+ if (!key.isEmpty()) {
+ d->sc_sequences = { key };
+ d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
+ }
+ if (member)
+ connect(this, SIGNAL(activated()), parent, member);
+ if (ambiguousMember)
+ connect(this, SIGNAL(activatedAmbiguously()), parent, ambiguousMember);
+}
+
+/*!
+ \since 6.0
+ Constructs a QShortcut object for the \a parent, which should be a
+ QWindow or a QWidget.
+
+ The shortcut operates on its parent, listening for \l{QShortcutEvent}s that
+ match the \a standardKey. Depending on the ambiguity of the event, the
+ shortcut will call the \a member function, or the \a ambiguousMember function,
+ if the key press was in the shortcut's \a context.
+*/
+QShortcut::QShortcut(QKeySequence::StandardKey standardKey, QObject *parent,
+ const char *member, const char *ambiguousMember,
+ Qt::ShortcutContext context)
+ : QShortcut(parent)
+{
+ Q_D(QShortcut);
+ d->sc_context = context;
+ d->sc_sequences = QKeySequence::keyBindings(standardKey);
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
if (member)
connect(this, SIGNAL(activated()), parent, member);
@@ -220,10 +219,7 @@ QShortcut::QShortcut(const QKeySequence &key, QObject *parent,
/*!
- \fn template<typename Functor>
- QShortcut(const QKeySequence &key, QObject *parent,
- Functor functor,
- Qt::ShortcutContext shortcutContext = Qt::WindowShortcut);
+ \fn template<typename Functor> QShortcut::QShortcut(const QKeySequence &key, QObject *parent, Functor functor, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
\since 5.15
\overload
@@ -231,10 +227,7 @@ QShortcut::QShortcut(const QKeySequence &key, QObject *parent,
\l{QShortcut::activated()}{activated()} signal to the \a functor.
*/
/*!
- \fn template<typename Functor>
- QShortcut(const QKeySequence &key, QObject *parent,
- const QObject *context, Functor functor,
- Qt::ShortcutContext shortcutContext = Qt::WindowShortcut);
+ \fn template<typename Functor> QShortcut::QShortcut(const QKeySequence &key, QObject *parent, const QObject *context, Functor functor, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
\since 5.15
\overload
@@ -246,46 +239,94 @@ QShortcut::QShortcut(const QKeySequence &key, QObject *parent,
If the \a context object is destroyed, the \a functor will not be called.
*/
/*!
- \fn template<typename Functor, typename FunctorAmbiguous>
- QShortcut(const QKeySequence &key, QObject *parent,
- const QObject *context1, Functor functor,
- FunctorAmbiguous functorAmbiguous,
- Qt::ShortcutContext shortcutContext = Qt::WindowShortcut);
+ \fn template<typename Functor, typename FunctorAmbiguous> QShortcut::QShortcut(const QKeySequence &key, QObject *parent, const QObject *context, Functor functor, FunctorAmbiguous functorAmbiguous, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
\since 5.15
\overload
This is a QShortcut convenience constructor which connects the shortcut's
\l{QShortcut::activated()}{activated()} signal to the \a functor and
\l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()}
- signal to the \a FunctorAmbiguous.
+ signal to the \a functorAmbiguous.
- The \a functor and \a FunctorAmbiguous can be a pointer to a member
+ The \a functor and \a functorAmbiguous can be a pointer to a member
function of the \a context object.
If the \a context object is destroyed, the \a functor and
- \a FunctorAmbiguous will not be called.
+ \a functorAmbiguous will not be called.
*/
/*!
- \fn template<typename Functor, typename FunctorAmbiguous>
- QShortcut(const QKeySequence &key, QObject *parent,
- const QObject *context1, Functor functor,
- const QObject *context2, FunctorAmbiguous functorAmbiguous,
- Qt::ShortcutContext shortcutContext = Qt::WindowShortcut);
+ \fn template<typename Functor, typename FunctorAmbiguous> QShortcut::QShortcut(const QKeySequence &key, QObject *parent, const QObject *context1, Functor functor, const QObject *context2, FunctorAmbiguous functorAmbiguous, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
\since 5.15
\overload
This is a QShortcut convenience constructor which connects the shortcut's
\l{QShortcut::activated()}{activated()} signal to the \a functor and
\l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()}
- signal to the \a FunctorAmbiguous.
+ signal to the \a functorAmbiguous.
+
+ The \a functor can be a pointer to a member function of the
+ \a context1 object.
+ The \a functorAmbiguous can be a pointer to a member function of the
+ \a context2 object.
+
+ If the \a context1 object is destroyed, the \a functor will not be called.
+ If the \a context2 object is destroyed, the \a functorAmbiguous
+ will not be called.
+*/
+
+/*!
+ \fn template<typename Functor> QShortcut::QShortcut(QKeySequence::StandardKey key, QObject *parent, Functor functor, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
+ \since 6.0
+ \overload
+
+ This is a QShortcut convenience constructor which connects the shortcut's
+ \l{QShortcut::activated()}{activated()} signal to the \a functor.
+*/
+/*!
+ \fn template<typename Functor> QShortcut::QShortcut(QKeySequence::StandardKey key, QObject *parent, const QObject *context, Functor functor, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
+ \since 6.0
+ \overload
+
+ This is a QShortcut convenience constructor which connects the shortcut's
+ \l{QShortcut::activated()}{activated()} signal to the \a functor.
+
+ The \a functor can be a pointer to a member function of the \a context object.
+
+ If the \a context object is destroyed, the \a functor will not be called.
+*/
+/*!
+ \fn template<typename Functor, typename FunctorAmbiguous> QShortcut::QShortcut(QKeySequence::StandardKey key, QObject *parent, const QObject *context, Functor functor, FunctorAmbiguous functorAmbiguous, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
+ \since 6.0
+ \overload
+
+ This is a QShortcut convenience constructor which connects the shortcut's
+ \l{QShortcut::activated()}{activated()} signal to the \a functor and
+ \l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()}
+ signal to the \a functorAmbiguous.
+
+ The \a functor and \a functorAmbiguous can be a pointer to a member
+ function of the \a context object.
+
+ If the \a context object is destroyed, the \a functor and
+ \a functorAmbiguous will not be called.
+*/
+/*!
+ \fn template<typename Functor, typename FunctorAmbiguous> QShortcut::QShortcut(QKeySequence::StandardKey key, QObject *parent, const QObject *context1, Functor functor, const QObject *context2, FunctorAmbiguous functorAmbiguous, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
+ \since 6.0
+ \overload
+
+ This is a QShortcut convenience constructor which connects the shortcut's
+ \l{QShortcut::activated()}{activated()} signal to the \a functor and
+ \l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()}
+ signal to the \a functorAmbiguous.
The \a functor can be a pointer to a member function of the
\a context1 object.
- The \a FunctorAmbiguous can be a pointer to a member function of the
+ The \a functorAmbiguous can be a pointer to a member function of the
\a context2 object.
If the \a context1 object is destroyed, the \a functor will not be called.
- If the \a context2 object is destroyed, the \a FunctorAmbiguous
+ If the \a context2 object is destroyed, the \a functorAmbiguous
will not be called.
*/
@@ -295,13 +336,15 @@ QShortcut::QShortcut(const QKeySequence &key, QObject *parent,
QShortcut::~QShortcut()
{
Q_D(QShortcut);
- if (qApp)
- QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(d->sc_id, this);
+ if (qApp) {
+ for (int id : std::as_const(d->sc_ids))
+ QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(id, this);
+ }
}
/*!
\property QShortcut::key
- \brief the shortcut's key sequence
+ \brief the shortcut's primary key sequence
This is a key sequence with an optional combination of Shift, Ctrl,
and Alt. The key sequence may be supplied in a number of ways:
@@ -312,18 +355,61 @@ QShortcut::~QShortcut()
*/
void QShortcut::setKey(const QKeySequence &key)
{
+ if (key.isEmpty())
+ setKeys({});
+ else
+ setKeys({ key });
+}
+
+QKeySequence QShortcut::key() const
+{
+ Q_D(const QShortcut);
+ if (d->sc_sequences.isEmpty())
+ return QKeySequence();
+ return d->sc_sequences.first();
+}
+
+/*!
+ Sets \a keys as the list of key sequences that trigger the
+ shortcut.
+
+ \since 6.0
+
+ \sa key, keys()
+*/
+void QShortcut::setKeys(const QList<QKeySequence> &keys)
+{
Q_D(QShortcut);
- if (d->sc_sequence == key)
+ if (d->sc_sequences == keys)
return;
- QAPP_CHECK("setKey");
- d->sc_sequence = key;
+ QAPP_CHECK("setKeys");
+ d->sc_sequences = keys;
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
}
-QKeySequence QShortcut::key() const
+/*!
+ Sets the triggers to those matching the standard key \a key.
+
+ \since 6.0
+
+ \sa key, keys()
+*/
+void QShortcut::setKeys(QKeySequence::StandardKey key)
+{
+ setKeys(QKeySequence::keyBindings(key));
+}
+
+/*!
+ Returns the list of key sequences which trigger this
+ shortcut.
+
+ \since 6.0
+ \sa key, setKeys()
+*/
+QList<QKeySequence> QShortcut::keys() const
{
Q_D(const QShortcut);
- return d->sc_sequence;
+ return d->sc_sequences;
}
/*!
@@ -348,7 +434,8 @@ void QShortcut::setEnabled(bool enable)
return;
QAPP_CHECK("setEnabled");
d->sc_enabled = enable;
- QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enable, d->sc_id, this);
+ for (int id : d->sc_ids)
+ QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enable, id, this);
}
bool QShortcut::isEnabled() const
@@ -401,7 +488,8 @@ void QShortcut::setAutoRepeat(bool on)
return;
QAPP_CHECK("setAutoRepeat");
d->sc_autorepeat = on;
- QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(on, d->sc_id, this);
+ for (int id : d->sc_ids)
+ QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(on, id, this);
}
bool QShortcut::autoRepeat() const
@@ -412,8 +500,7 @@ bool QShortcut::autoRepeat() const
/*!
- \property QShortcut::whatsThis
- \brief the shortcut's "What's This?" help text
+ Sets the shortcut's "What's This?" help \a text.
The text will be shown when a widget application is in "What's
This?" mode and the user types the shortcut key() sequence.
@@ -421,9 +508,9 @@ bool QShortcut::autoRepeat() const
To set "What's This?" help on a menu item (with or without a
shortcut key), set the help on the item's action.
- By default, this property contains an empty string.
+ By default, the help text is an empty string.
- This property has no effect in applications that don't use
+ This function has no effect in applications that don't use
widgets.
\sa QWhatsThis::inWhatsThisMode(), QAction::setWhatsThis()
@@ -434,23 +521,33 @@ void QShortcut::setWhatsThis(const QString &text)
d->sc_whatsthis = text;
}
+/*!
+ Returns the shortcut's "What's This?" help text.
+
+ \sa setWhatsThis()
+*/
QString QShortcut::whatsThis() const
{
Q_D(const QShortcut);
return d->sc_whatsthis;
}
-
+#if QT_DEPRECATED_SINCE(6,0)
/*!
- Returns the shortcut's ID.
+ Returns the primary key binding's ID.
+
+ \deprecated
\sa QShortcutEvent::shortcutId()
*/
int QShortcut::id() const
{
Q_D(const QShortcut);
- return d->sc_id;
+ if (d->sc_ids.isEmpty())
+ return 0;
+ return d->sc_ids.first();
}
+#endif
/*!
\fn QWidget *QShortcut::parentWidget() const
@@ -466,8 +563,8 @@ bool QShortcut::event(QEvent *e)
Q_D(QShortcut);
if (d->sc_enabled && e->type() == QEvent::Shortcut) {
auto se = static_cast<QShortcutEvent *>(e);
- if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence
- && !d->handleWhatsThis()) {
+ if (!d->handleWhatsThis()) {
+ Q_ASSERT_X(d->sc_ids.contains(se->shortcutId()), "QShortcut::event", "Received shortcut event from wrong shortcut");
if (se->isAmbiguous())
emit activatedAmbiguously();
else