Extract QGuiShortcut

[ChangeLog][QtGui] Added QGuiShortcut and made the equivalent
existing classes in Qt Widgets derive from them. This provides
basic functionality for adding shortcut handling in QML.

Fixes: QTBUG-79638
Task-number: QTBUG-76493
Change-Id: I5bbd2c8f192660e93c4690b9f894643275090e4d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Friedemann Kleint 2019-10-22 10:53:54 +02:00
parent 5367f76e17
commit 89f1f14c5e
9 changed files with 659 additions and 255 deletions

View File

@ -169,10 +169,13 @@ qtConfig(opengl) {
qtConfig(shortcut) {
HEADERS += \
kernel/qguishortcut.h \
kernel/qguishortcut_p.h \
kernel/qshortcutmap_p.h \
kernel/qkeysequence.h \
kernel/qkeysequence_p.h
SOURCES += \
kernel/qguishortcut.cpp \
kernel/qshortcutmap.cpp \
kernel/qkeysequence.cpp
}

View File

@ -0,0 +1,354 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#include "qguishortcut.h"
#include "qguishortcut_p.h"
#include <qevent.h>
#include <qguiapplication.h>
#include <qwindow.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformmenu.h>
QT_BEGIN_NAMESPACE
#define QAPP_CHECK(functionName) \
if (Q_UNLIKELY(!qApp)) { \
qWarning("QGuiShortcut: Initialize QGuiApplication before calling '" functionName "'."); \
return; \
}
/*!
\class QGuiShortcut
\brief The QGuiShortcut class is a base class for handling keyboard shortcuts.
\ingroup events
\inmodule QtGui
\since 6.0
The QGuiShortcut class is a base class for classes providing a way of
connecting keyboard shortcuts to Qt's \l{signals and slots} mechanism,
so that objects can be informed when a shortcut is executed. The shortcut
can be set up to contain all the key presses necessary to
describe a keyboard shortcut, including the states of modifier
keys such as \uicontrol Shift, \uicontrol Ctrl, and \uicontrol Alt.
\target mnemonic
\sa QShortcutEvent, QKeySequence, QAction
*/
/*!
\fn void QGuiShortcut::activated()
This signal is emitted when the user types the shortcut's key
sequence.
\sa activatedAmbiguously()
*/
/*!
\fn void QGuiShortcut::activatedAmbiguously()
When a key sequence is being typed at the keyboard, it is said to
be ambiguous as long as it matches the start of more than one
shortcut.
When a shortcut's key sequence is completed,
activatedAmbiguously() is emitted if the key sequence is still
ambiguous (i.e., it is the start of one or more other shortcuts).
The activated() signal is not emitted in this case.
\sa activated()
*/
static bool simpleContextMatcher(QObject *object, Qt::ShortcutContext context)
{
auto guiShortcut = qobject_cast<QGuiShortcut *>(object);
if (QGuiApplication::applicationState() != Qt::ApplicationActive || guiShortcut == nullptr)
return false;
if (context == Qt::ApplicationShortcut)
return true;
auto focusWindow = QGuiApplication::focusWindow();
if (!focusWindow)
return false;
auto window = qobject_cast<const QWindow *>(guiShortcut->parent());
if (!window)
return false;
if (focusWindow == window && focusWindow->isTopLevel())
return context == Qt::WindowShortcut || context == Qt::WidgetWithChildrenShortcut;
return focusWindow->isAncestorOf(window, QWindow::ExcludeTransients);
}
QShortcutMap::ContextMatcher QGuiShortcutPrivate::contextMatcher() const
{
return simpleContextMatcher;
}
void QGuiShortcutPrivate::redoGrab(QShortcutMap &map)
{
Q_Q(QGuiShortcut);
if (Q_UNLIKELY(!parent)) {
qWarning("QGuiShortcut: No window parent defined");
return;
}
if (sc_id)
map.removeShortcut(sc_id, q);
if (sc_sequence.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);
}
/*!
Constructs a QGuiShortcut object for the \a parent window. Since no
shortcut key sequence is specified, the shortcut will not emit any
signals.
\sa setKey()
*/
QGuiShortcut::QGuiShortcut(QWindow *parent)
: QGuiShortcut(*new QGuiShortcutPrivate, parent)
{
}
/*!
Constructs a QGuiShortcut object for the \a parent window. The shortcut
operates on its parent, listening for \l{QShortcutEvent}s that
match the \a key sequence. 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.
*/
QGuiShortcut::QGuiShortcut(const QKeySequence &key, QWindow *parent,
const char *member, const char *ambiguousMember,
Qt::ShortcutContext context)
: QGuiShortcut(*new QGuiShortcutPrivate, key, parent, member, ambiguousMember, context)
{
}
/*!
\internal
*/
QGuiShortcut::QGuiShortcut(QGuiShortcutPrivate &dd, QObject *parent)
: QObject(dd, parent)
{
Q_ASSERT(parent != nullptr);
}
/*!
\internal
*/
QGuiShortcut::QGuiShortcut(QGuiShortcutPrivate &dd,
const QKeySequence &key, QObject *parent,
const char *member, const char *ambiguousMember,
Qt::ShortcutContext context)
: QGuiShortcut(dd, parent)
{
QAPP_CHECK("QGuiShortcut");
Q_D(QGuiShortcut);
d->sc_context = context;
d->sc_sequence = key;
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
if (member)
connect(this, SIGNAL(activated()), parent, member);
if (ambiguousMember)
connect(this, SIGNAL(activatedAmbiguously()), parent, ambiguousMember);
}
/*!
Destroys the shortcut.
*/
QGuiShortcut::~QGuiShortcut()
{
Q_D(QGuiShortcut);
if (qApp)
QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(d->sc_id, this);
}
/*!
\property QGuiShortcut::key
\brief the shortcut's 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:
\snippet code/src_gui_kernel_qshortcut.cpp 1
By default, this property contains an empty key sequence.
*/
void QGuiShortcut::setKey(const QKeySequence &key)
{
Q_D(QGuiShortcut);
if (d->sc_sequence == key)
return;
QAPP_CHECK("setKey");
d->sc_sequence = key;
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
}
QKeySequence QGuiShortcut::key() const
{
Q_D(const QGuiShortcut);
return d->sc_sequence;
}
/*!
\property QGuiShortcut::enabled
\brief whether the shortcut is enabled
An enabled shortcut emits the activated() or activatedAmbiguously()
signal when a QShortcutEvent occurs that matches the shortcut's
key() sequence.
If the application is in \c WhatsThis mode the shortcut will not emit
the signals, but will show the "What's This?" text instead.
By default, this property is \c true.
\sa whatsThis
*/
void QGuiShortcut::setEnabled(bool enable)
{
Q_D(QGuiShortcut);
if (d->sc_enabled == enable)
return;
QAPP_CHECK("setEnabled");
d->sc_enabled = enable;
QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enable, d->sc_id, this);
}
bool QGuiShortcut::isEnabled() const
{
Q_D(const QGuiShortcut);
return d->sc_enabled;
}
/*!
\property QGuiShortcut::context
\brief the context in which the shortcut is valid
A shortcut's context decides in which circumstances a shortcut is
allowed to be triggered. The normal context is Qt::WindowShortcut,
which allows the shortcut to trigger if the parent (the widget
containing the shortcut) is a subwidget of the active top-level
window.
By default, this property is set to Qt::WindowShortcut.
*/
void QGuiShortcut::setContext(Qt::ShortcutContext context)
{
Q_D(QGuiShortcut);
if (d->sc_context == context)
return;
QAPP_CHECK("setContext");
d->sc_context = context;
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
}
Qt::ShortcutContext QGuiShortcut::context() const
{
Q_D(const QGuiShortcut);
return d->sc_context;
}
/*!
\property QGuiShortcut::autoRepeat
\brief whether the shortcut can auto repeat
If true, the shortcut will auto repeat when the keyboard shortcut
combination is held down, provided that keyboard auto repeat is
enabled on the system.
The default value is true.
*/
void QGuiShortcut::setAutoRepeat(bool on)
{
Q_D(QGuiShortcut);
if (d->sc_autorepeat == on)
return;
QAPP_CHECK("setAutoRepeat");
d->sc_autorepeat = on;
QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(on, d->sc_id, this);
}
bool QGuiShortcut::autoRepeat() const
{
Q_D(const QGuiShortcut);
return d->sc_autorepeat;
}
/*!
Returns the shortcut's ID.
\sa QShortcutEvent::shortcutId()
*/
int QGuiShortcut::id() const
{
Q_D(const QGuiShortcut);
return d->sc_id;
}
/*!
\internal
*/
bool QGuiShortcut::event(QEvent *e)
{
Q_D(QGuiShortcut);
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 (se->isAmbiguous())
emit activatedAmbiguously();
else
emit activated();
return true;
}
}
return QObject::event(e);
}
QT_END_NAMESPACE
#include "moc_qguishortcut.cpp"

View File

@ -0,0 +1,98 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef QGUISHORTCUT_H
#define QGUISHORTCUT_H
#include <QtGui/qtguiglobal.h>
#include <QtGui/qkeysequence.h>
#include <QtCore/qobject.h>
QT_REQUIRE_CONFIG(shortcut);
QT_BEGIN_NAMESPACE
class QGuiShortcutPrivate;
class QWindow;
class Q_GUI_EXPORT QGuiShortcut : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QGuiShortcut)
Q_PROPERTY(QKeySequence key READ key WRITE setKey)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat)
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext)
public:
explicit QGuiShortcut(QWindow *parent);
explicit QGuiShortcut(const QKeySequence& key, QWindow *parent,
const char *member = nullptr, const char *ambiguousMember = nullptr,
Qt::ShortcutContext context = Qt::WindowShortcut);
~QGuiShortcut();
void setKey(const QKeySequence& key);
QKeySequence key() const;
void setEnabled(bool enable);
bool isEnabled() const;
void setContext(Qt::ShortcutContext context);
Qt::ShortcutContext context() const;
void setAutoRepeat(bool on);
bool autoRepeat() const;
int id() const;
Q_SIGNALS:
void activated();
void activatedAmbiguously();
protected:
QGuiShortcut(QGuiShortcutPrivate &dd, QObject *parent);
QGuiShortcut(QGuiShortcutPrivate &dd, const QKeySequence& key, QObject *parent,
const char *member, const char *ambiguousMember,
Qt::ShortcutContext context);
bool event(QEvent *e) override;
};
QT_END_NAMESPACE
#endif // QGUISHORTCUT_H

View File

@ -0,0 +1,92 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/
#ifndef QGUISHORTCUT_P_H
#define QGUISHORTCUT_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtGui/private/qtguiglobal_p.h>
#include "qguishortcut.h"
#include <QtGui/qkeysequence.h>
#include <QtCore/qstring.h>
#include <QtCore/private/qobject_p.h>
#include <private/qshortcutmap_p.h>
QT_BEGIN_NAMESPACE
class QShortcutMap;
/*
\internal
Private data accessed through d-pointer.
*/
class Q_GUI_EXPORT QGuiShortcutPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGuiShortcut)
public:
QGuiShortcutPrivate() = default;
virtual QShortcutMap::ContextMatcher contextMatcher() const;
virtual bool handleWhatsThis() { return false; }
QKeySequence sc_sequence;
Qt::ShortcutContext sc_context = Qt::WindowShortcut;
bool sc_enabled = true;
bool sc_autorepeat = true;
int sc_id = 0;
void redoGrab(QShortcutMap &map);
};
QT_END_NAMESPACE
#endif // QGUISHORTCUT_P_H

View File

@ -52,6 +52,7 @@
#endif
#include <qapplication.h>
#include <private/qapplication_p.h>
#include "private/qguishortcut_p.h"
#include <private/qshortcutmap_p.h>
#if QT_CONFIG(action)
# include <private/qaction_p.h>
@ -61,13 +62,6 @@
QT_BEGIN_NAMESPACE
#define QAPP_CHECK(functionName) \
if (Q_UNLIKELY(!qApp)) { \
qWarning("QShortcut: Initialize QApplication before calling '" functionName "'."); \
return; \
}
static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window);
#if QT_CONFIG(graphicsview)
static bool correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window);
@ -396,65 +390,30 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge
Returns the shortcut's parent widget.
*/
/*!
\fn void QShortcut::activated()
This signal is emitted when the user types the shortcut's key
sequence.
\sa activatedAmbiguously()
*/
/*!
\fn void QShortcut::activatedAmbiguously()
When a key sequence is being typed at the keyboard, it is said to
be ambiguous as long as it matches the start of more than one
shortcut.
When a shortcut's key sequence is completed,
activatedAmbiguously() is emitted if the key sequence is still
ambiguous (i.e., it is the start of one or more other shortcuts).
The activated() signal is not emitted in this case.
\sa activated()
*/
/*
\internal
Private data accessed through d-pointer.
*/
class QShortcutPrivate : public QObjectPrivate
class QShortcutPrivate : public QGuiShortcutPrivate
{
Q_DECLARE_PUBLIC(QShortcut)
public:
QShortcutPrivate() = default;
QKeySequence sc_sequence;
Qt::ShortcutContext sc_context = Qt::WindowShortcut;
bool sc_enabled = true;
bool sc_autorepeat = true;
int sc_id = 0;
QShortcutMap::ContextMatcher contextMatcher() const override
{ return qWidgetShortcutContextMatcher; }
bool handleWhatsThis() override;
QString sc_whatsthis;
void redoGrab(QShortcutMap &map);
};
void QShortcutPrivate::redoGrab(QShortcutMap &map)
bool QShortcutPrivate::handleWhatsThis()
{
Q_Q(QShortcut);
if (Q_UNLIKELY(!parent)) {
qWarning("QShortcut: No widget parent defined");
return;
}
if (sc_id)
map.removeShortcut(sc_id, q);
if (sc_sequence.isEmpty())
return;
sc_id = map.addShortcut(q, sc_sequence, sc_context, qWidgetShortcutContextMatcher);
if (!sc_enabled)
map.setShortcutEnabled(false, sc_id, q);
if (!sc_autorepeat)
map.setShortcutAutoRepeat(false, sc_id, q);
const bool result = QWhatsThis::inWhatsThisMode();
if (result)
QWhatsThis::showText(QCursor::pos(), sc_whatsthis);
return result;
}
/*!
@ -465,9 +424,8 @@ void QShortcutPrivate::redoGrab(QShortcutMap &map)
\sa setKey()
*/
QShortcut::QShortcut(QWidget *parent)
: QObject(*new QShortcutPrivate, parent)
: QGuiShortcut(*new QShortcutPrivate, parent)
{
Q_ASSERT(parent != nullptr);
}
/*!
@ -481,114 +439,8 @@ QShortcut::QShortcut(QWidget *parent)
QShortcut::QShortcut(const QKeySequence &key, QWidget *parent,
const char *member, const char *ambiguousMember,
Qt::ShortcutContext context)
: QShortcut(parent)
: QGuiShortcut(*new QShortcutPrivate, key, parent, member, ambiguousMember, context)
{
QAPP_CHECK("QShortcut");
Q_D(QShortcut);
d->sc_context = context;
d->sc_sequence = key;
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
if (member)
connect(this, SIGNAL(activated()), parent, member);
if (ambiguousMember)
connect(this, SIGNAL(activatedAmbiguously()), parent, ambiguousMember);
}
/*!
Destroys the shortcut.
*/
QShortcut::~QShortcut()
{
Q_D(QShortcut);
if (qApp)
QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(d->sc_id, this);
}
/*!
\property QShortcut::key
\brief the shortcut's 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:
\snippet code/src_gui_kernel_qshortcut.cpp 1
By default, this property contains an empty key sequence.
*/
void QShortcut::setKey(const QKeySequence &key)
{
Q_D(QShortcut);
if (d->sc_sequence == key)
return;
QAPP_CHECK("setKey");
d->sc_sequence = key;
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
}
QKeySequence QShortcut::key() const
{
Q_D(const QShortcut);
return d->sc_sequence;
}
/*!
\property QShortcut::enabled
\brief whether the shortcut is enabled
An enabled shortcut emits the activated() or activatedAmbiguously()
signal when a QShortcutEvent occurs that matches the shortcut's
key() sequence.
If the application is in \c WhatsThis mode the shortcut will not emit
the signals, but will show the "What's This?" text instead.
By default, this property is \c true.
\sa whatsThis
*/
void QShortcut::setEnabled(bool enable)
{
Q_D(QShortcut);
if (d->sc_enabled == enable)
return;
QAPP_CHECK("setEnabled");
d->sc_enabled = enable;
QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enable, d->sc_id, this);
}
bool QShortcut::isEnabled() const
{
Q_D(const QShortcut);
return d->sc_enabled;
}
/*!
\property QShortcut::context
\brief the context in which the shortcut is valid
A shortcut's context decides in which circumstances a shortcut is
allowed to be triggered. The normal context is Qt::WindowShortcut,
which allows the shortcut to trigger if the parent (the widget
containing the shortcut) is a subwidget of the active top-level
window.
By default, this property is set to Qt::WindowShortcut.
*/
void QShortcut::setContext(Qt::ShortcutContext context)
{
Q_D(QShortcut);
if(d->sc_context == context)
return;
QAPP_CHECK("setContext");
d->sc_context = context;
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
}
Qt::ShortcutContext QShortcut::context() const
{
Q_D(const QShortcut);
return d->sc_context;
}
/*!
@ -618,66 +470,8 @@ QString QShortcut::whatsThis() const
}
/*!
\property QShortcut::autoRepeat
\brief whether the shortcut can auto repeat
\since 4.2
If true, the shortcut will auto repeat when the keyboard shortcut
combination is held down, provided that keyboard auto repeat is
enabled on the system.
The default value is true.
Destroys the shortcut.
*/
void QShortcut::setAutoRepeat(bool on)
{
Q_D(QShortcut);
if (d->sc_autorepeat == on)
return;
QAPP_CHECK("setAutoRepeat");
d->sc_autorepeat = on;
QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(on, d->sc_id, this);
}
bool QShortcut::autoRepeat() const
{
Q_D(const QShortcut);
return d->sc_autorepeat;
}
/*!
Returns the shortcut's ID.
\sa QShortcutEvent::shortcutId()
*/
int QShortcut::id() const
{
Q_D(const QShortcut);
return d->sc_id;
}
/*!
\internal
*/
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){
#if QT_CONFIG(whatsthis)
if (QWhatsThis::inWhatsThisMode()) {
QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
} else
#endif
if (se->isAmbiguous())
emit activatedAmbiguously();
else
emit activated();
return true;
}
}
return QObject::event(e);
}
QShortcut::~QShortcut() = default;
QT_END_NAMESPACE
#include "moc_qshortcut.cpp"

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@ -42,55 +42,30 @@
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qwidget.h>
#include <QtGui/qkeysequence.h>
#include <QtGui/qguishortcut.h>
QT_REQUIRE_CONFIG(shortcut);
QT_BEGIN_NAMESPACE
class QShortcutPrivate;
class Q_WIDGETS_EXPORT QShortcut : public QObject
class Q_WIDGETS_EXPORT QShortcut : public QGuiShortcut
{
Q_OBJECT
Q_DECLARE_PRIVATE(QShortcut)
Q_PROPERTY(QKeySequence key READ key WRITE setKey)
Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat)
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext)
Q_DECLARE_PRIVATE(QShortcut)
public:
explicit QShortcut(QWidget *parent);
QShortcut(const QKeySequence& key, QWidget *parent,
explicit QShortcut(const QKeySequence& key, QWidget *parent,
const char *member = nullptr, const char *ambiguousMember = nullptr,
Qt::ShortcutContext context = Qt::WindowShortcut);
~QShortcut();
void setKey(const QKeySequence& key);
QKeySequence key() const;
void setEnabled(bool enable);
bool isEnabled() const;
void setContext(Qt::ShortcutContext context);
Qt::ShortcutContext context() const;
void setWhatsThis(const QString &text);
QString whatsThis() const;
void setAutoRepeat(bool on);
bool autoRepeat() const;
int id() const;
inline QWidget *parentWidget() const
{ return static_cast<QWidget *>(QObject::parent()); }
Q_SIGNALS:
void activated();
void activatedAmbiguously();
protected:
bool event(QEvent *e) override;
};
QT_END_NAMESPACE

View File

@ -11,6 +11,7 @@ SUBDIRS=\
qguieventdispatcher \
qguieventloop \
qguimetatype \
qguishortcut \
qguitimer \
qguivariant \
qhighdpiscaling \
@ -33,6 +34,7 @@ win32:!winrt:qtHaveModule(network): SUBDIRS += noqteventloop
!qtConfig(shortcut): SUBDIRS -= \
qkeysequence \
qguishortcut \
qguimetatype \
qguivariant

View File

@ -0,0 +1,4 @@
CONFIG += testcase
TARGET = tst_qguishortcut
QT += testlib
SOURCES += tst_qguishortcut.cpp

View File

@ -0,0 +1,82 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QtGui/qguiapplication.h>
#include <QtGui/qguishortcut.h>
#include <QtGui/qpainter.h>
#include <QtGui/qrasterwindow.h>
#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h>
class tst_QGuiShortcut : public QObject
{
Q_OBJECT
public:
private slots:
void trigger();
};
class ColoredWindow : public QRasterWindow {
public:
ColoredWindow(QColor c) : m_color(c) {}
protected:
void paintEvent(QPaintEvent *event) override;
private:
const QColor m_color;
};
void ColoredWindow::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.fillRect(QRect(QPoint(), size()), m_color);
}
static void sendKey(QWindow *target, Qt::Key k, char c, Qt::KeyboardModifiers modifiers)
{
QTest::sendKeyEvent(QTest::Press, target, k, c, modifiers);
QTest::sendKeyEvent(QTest::Release, target, k, c, modifiers);
}
void tst_QGuiShortcut::trigger()
{
ColoredWindow w(Qt::yellow);
w.setTitle(QTest::currentTestFunction());
w.resize(QGuiApplication::primaryScreen()->size() / 4);
new QGuiShortcut(Qt::CTRL + Qt::Key_Q, &w, SLOT(close()));
w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w));
sendKey(&w, Qt::Key_Q, 'q', Qt::ControlModifier);
QTRY_VERIFY(!w.isVisible());
}
QTEST_MAIN(tst_QGuiShortcut)
#include "tst_qguishortcut.moc"