Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qquickshortcut.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#
include
"qquickshortcut_p.h"
6
7
#
include
<
QtQuick
/
qquickitem
.
h
>
8
#
include
<
QtQuick
/
qquickwindow
.
h
>
9
#
include
<
QtQuick
/
private
/
qquickrendercontrol_p
.
h
>
10
#
include
<
QtQuick
/
private
/
qtquickglobal_p
.
h
>
11
#
include
<
QtGui
/
private
/
qguiapplication_p
.
h
>
12
#
include
<
QtQml
/
qqmlinfo
.
h
>
13
14
QT_BEGIN_NAMESPACE
15
16
/*!
17
\qmltype Shortcut
18
\nativetype QQuickShortcut
19
\inqmlmodule QtQuick
20
\since 5.5
21
\ingroup qtquick-input
22
\brief Provides keyboard shortcuts.
23
24
The Shortcut type lets you handle keyboard shortcuts. The shortcut can
25
be set to one of the
26
\l{QKeySequence::StandardKey}{standard keyboard shortcuts},
27
or it can be described with a string containing a sequence of up to four key
28
presses that are needed to \l{Shortcut::activated}{activate} the shortcut.
29
30
\qml
31
Item {
32
id: view
33
34
property int currentIndex
35
36
Shortcut {
37
sequences: [StandardKey.NextChild]
38
onActivated: view.currentIndex++
39
}
40
}
41
\endqml
42
43
It is also possible to set multiple shortcut \l sequences, so that the shortcut
44
can be \l activated via several different sequences of key presses.
45
46
\sa Keys, {Keys::}{shortcutOverride()}
47
*/
48
49
/*! \qmlsignal QtQuick::Shortcut::activated()
50
51
This signal is emitted when the shortcut is activated.
52
*/
53
54
/*! \qmlsignal QtQuick::Shortcut::activatedAmbiguously()
55
56
This signal is emitted when the shortcut is activated ambigously,
57
meaning that it matches the start of more than one shortcut.
58
*/
59
60
static
bool
qQuickShortcutContextMatcher
(QObject *obj, Qt::ShortcutContext context)
61
{
62
switch
(context) {
63
case
Qt::ApplicationShortcut:
64
return
true
;
65
case
Qt::WindowShortcut: {
66
while
(obj && !obj->isWindowType()) {
67
obj = obj->parent();
68
if
(QQuickItem *item = qobject_cast<QQuickItem *>(obj))
69
obj = item->window();
70
}
71
const
QWindow *focusWindow = QGuiApplication::focusWindow();
72
if
(!obj || !focusWindow)
73
return
false
;
74
if
(obj == focusWindow)
75
return
true
;
76
return
QQuickRenderControlPrivate::isFocusWindowFor(
77
qobject_cast<QQuickWindow *>(obj), focusWindow);
78
}
79
default
:
80
return
false
;
81
}
82
}
83
84
typedef
bool
(*
ContextMatcher
)(QObject *,
Qt
::
ShortcutContext
);
85
86
Q_GLOBAL_STATIC_WITH_ARGS(
ContextMatcher
, ctxMatcher, (qQuickShortcutContextMatcher))
87
88
Q_QUICK_EXPORT ContextMatcher qt_quick_shortcut_context_matcher()
89
{
90
return
*ctxMatcher();
91
}
92
93
Q_QUICK_EXPORT
void
qt_quick_set_shortcut_context_matcher
(
ContextMatcher
matcher)
94
{
95
if
(!ctxMatcher.isDestroyed())
96
*ctxMatcher() = matcher;
97
}
98
99
static
QKeySequence
valueToKeySequence
(
const
QVariant &value,
const
QQuickShortcut *
const
shortcut)
100
{
101
if
(value.userType() == QMetaType::Int) {
102
const
QList<QKeySequence> s =
103
QKeySequence::keyBindings(
static_cast
<QKeySequence::StandardKey>(value.toInt()));
104
if
(s.size() > 1) {
105
const
QString templateString = QString::fromUtf16(
106
u"Shortcut: Only binding to one of multiple key bindings associated with %1. "
107
u"Use 'sequences: [ <key> ]' to bind to all of them.");
108
qmlWarning(shortcut)
109
<< templateString.arg(
static_cast
<QKeySequence::StandardKey>(value.toInt()));
110
}
111
return
s.size() > 0 ? s[0] : QKeySequence {};
112
}
else
if
(value.userType() == QMetaType::QKeySequence) {
113
return
value.value<QKeySequence>();
114
}
115
116
return
QKeySequence::fromString(value.toString());
117
}
118
119
static
QList
<
QKeySequence
>
valueToKeySequences
(
const
QVariant &value)
120
{
121
if
(value.userType() == QMetaType::Int) {
122
return
QKeySequence::keyBindings(
static_cast
<QKeySequence::StandardKey>(value.toInt()));
123
}
else
{
124
QList<QKeySequence> result;
125
if
(value.userType() == QMetaType::QKeySequence)
126
result.push_back(value.value<QKeySequence>());
127
else
128
result.push_back(QKeySequence::fromString(value.toString()));
129
return
result;
130
}
131
}
132
133
QQuickShortcut::QQuickShortcut(QObject *parent) : QObject(parent),
134
m_enabled(
true
), m_completed(
false
), m_autorepeat(
true
), m_context(Qt::WindowShortcut)
135
{
136
}
137
138
QQuickShortcut::~QQuickShortcut()
139
{
140
ungrabShortcut(m_shortcut);
141
for
(Shortcut &shortcut : m_shortcuts)
142
ungrabShortcut(shortcut);
143
}
144
145
/*!
146
\qmlproperty keysequence QtQuick::Shortcut::sequence
147
148
This property holds the shortcut's key sequence. The key sequence can be set
149
to one of the \l{QKeySequence::StandardKey}{standard keyboard shortcuts}, or
150
it can be described with a string containing a sequence of up to four key
151
presses that are needed to \l{Shortcut::activated}{activate} the shortcut.
152
153
The default value is an empty key sequence.
154
155
\qml
156
Shortcut {
157
sequence: "Ctrl+E,Ctrl+W"
158
onActivated: edit.wrapMode = TextEdit.Wrap
159
}
160
\endqml
161
162
\note Given that standard keys can resolve to one shortcut on some
163
platforms, but multiple shortcuts on other platforms, we recommend always
164
using \l{Shortcut::}{sequences} for standard keys.
165
166
\sa sequences
167
*/
168
QVariant QQuickShortcut::sequence()
const
169
{
170
return
m_shortcut.userValue;
171
}
172
173
void
QQuickShortcut::setSequence(
const
QVariant &value)
174
{
175
if
(value == m_shortcut.userValue)
176
return
;
177
178
QKeySequence keySequence = valueToKeySequence(value,
this
);
179
180
ungrabShortcut(m_shortcut);
181
m_shortcut.userValue = value;
182
m_shortcut.keySequence = keySequence;
183
grabShortcut(m_shortcut, m_context);
184
emit sequenceChanged();
185
if
(m_shortcuts.isEmpty()) {
186
// The text only changes if m_shortcuts contained no entry
187
// as we prefer the entry from there otherwise
188
emit nativeTextChanged();
189
emit portableTextChanged();
190
}
191
}
192
193
/*!
194
\qmlproperty list<keysequence> QtQuick::Shortcut::sequences
195
\since 5.9
196
197
This property holds multiple key sequences for the shortcut. The key sequences
198
can be set to one of the \l{QKeySequence::StandardKey}{standard keyboard shortcuts},
199
or they can be described with strings containing sequences of up to four key
200
presses that are needed to \l{Shortcut::activated}{activate} the shortcut.
201
202
\qml
203
Shortcut {
204
sequences: [StandardKey.Cut, "Ctrl+X", "Shift+Del"]
205
onActivated: edit.cut()
206
}
207
\endqml
208
*/
209
QVariantList QQuickShortcut::sequences()
const
210
{
211
QVariantList values;
212
for
(
const
Shortcut &shortcut : m_shortcuts)
213
values += shortcut.userValue;
214
return
values;
215
}
216
217
void
QQuickShortcut::setSequences(
const
QVariantList &values)
218
{
219
// convert QVariantList to QList<QKeySequence>
220
QList<Shortcut> requestedShortcuts;
221
for
(
const
QVariant &v : values) {
222
const
QList<QKeySequence> list = valueToKeySequences(v);
223
for
(
const
QKeySequence &s : list) {
224
Shortcut sc;
225
sc.userValue = v;
226
sc.keySequence = s;
227
requestedShortcuts.push_back(sc);
228
}
229
}
230
231
// if nothing has changed, just return:
232
if
(m_shortcuts.size() == requestedShortcuts.size()) {
233
bool
changed =
false
;
234
for
(
int
i = 0; i < requestedShortcuts.size(); ++i) {
235
const
Shortcut &requestedShortcut = requestedShortcuts[i];
236
const
Shortcut &shortcut = m_shortcuts[i];
237
if
(!(requestedShortcut.userValue == shortcut.userValue
238
&& requestedShortcut.keySequence == shortcut.keySequence)) {
239
changed =
true
;
240
break
;
241
}
242
}
243
if
(!changed) {
244
return
;
245
}
246
}
247
248
const
Shortcut oldUsedShortcut = m_shortcuts.isEmpty() ? m_shortcut
249
: m_shortcuts.first();
250
251
for
(Shortcut &s : m_shortcuts)
252
ungrabShortcut(s);
253
m_shortcuts = requestedShortcuts;
254
for
(Shortcut &s : m_shortcuts)
255
grabShortcut(s, m_context);
256
257
const
Shortcut currentUsedShortcut = m_shortcuts.isEmpty() ? m_shortcut
258
: m_shortcuts.first();
259
260
emit sequencesChanged();
261
if
(oldUsedShortcut.keySequence != currentUsedShortcut.keySequence) {
262
emit nativeTextChanged();
263
emit portableTextChanged();
264
}
265
}
266
267
/*!
268
\qmlproperty string QtQuick::Shortcut::nativeText
269
\since 5.6
270
271
This property provides the shortcut's key sequence as a platform specific
272
string. This means that it will be shown translated, and on \macos it will
273
resemble a key sequence from the menu bar. It is best to display this text
274
to the user (for example, on a tooltip).
275
276
\include qquickshortcut.qdocinc multishortcut
277
278
\sa sequence, portableText
279
*/
280
QString QQuickShortcut::nativeText()
const
281
{
282
const
Shortcut &shortCut = m_shortcuts.isEmpty() ? m_shortcut
283
: m_shortcuts.front();
284
return
shortCut.keySequence.toString(QKeySequence::NativeText);
285
}
286
287
/*!
288
\qmlproperty string QtQuick::Shortcut::portableText
289
\since 5.6
290
291
This property provides the shortcut's key sequence as a string in a
292
"portable" format, suitable for reading and writing to a file. In many
293
cases, it will look similar to the native text on Windows and X11.
294
295
\include qquickshortcut.qdocinc multishortcut
296
297
\sa sequence, nativeText
298
*/
299
QString QQuickShortcut::portableText()
const
300
{
301
const
Shortcut &shortCut = m_shortcuts.isEmpty() ? m_shortcut
302
: m_shortcuts.front();
303
return
shortCut.keySequence.toString(QKeySequence::PortableText);
304
}
305
306
/*!
307
\qmlproperty bool QtQuick::Shortcut::enabled
308
309
This property holds whether the shortcut is enabled.
310
311
The default value is \c true.
312
*/
313
bool
QQuickShortcut::isEnabled()
const
314
{
315
return
m_enabled;
316
}
317
318
void
QQuickShortcut::setEnabled(
bool
enabled)
319
{
320
if
(enabled == m_enabled)
321
return
;
322
323
setEnabled(m_shortcut, enabled);
324
for
(Shortcut &shortcut : m_shortcuts)
325
setEnabled(shortcut, enabled);
326
327
m_enabled = enabled;
328
emit enabledChanged();
329
}
330
331
/*!
332
\qmlproperty bool QtQuick::Shortcut::autoRepeat
333
334
This property holds whether the shortcut can auto repeat.
335
336
The default value is \c true.
337
*/
338
bool
QQuickShortcut::autoRepeat()
const
339
{
340
return
m_autorepeat;
341
}
342
343
void
QQuickShortcut::setAutoRepeat(
bool
repeat)
344
{
345
if
(repeat == m_autorepeat)
346
return
;
347
348
setAutoRepeat(m_shortcut, repeat);
349
for
(Shortcut &shortcut : m_shortcuts)
350
setAutoRepeat(shortcut, repeat);
351
352
m_autorepeat = repeat;
353
emit autoRepeatChanged();
354
}
355
356
/*!
357
\qmlproperty enumeration QtQuick::Shortcut::context
358
359
This property holds the \l{Qt::ShortcutContext}{shortcut context}.
360
361
Supported values are:
362
363
\value Qt.WindowShortcut
364
(default) The shortcut is active when its parent item is in an active top-level window.
365
\value Qt.ApplicationShortcut
366
The shortcut is active when one of the application's windows are active.
367
368
\qml
369
Shortcut {
370
sequence: StandardKey.Quit
371
context: Qt.ApplicationShortcut
372
onActivated: Qt.quit()
373
}
374
\endqml
375
*/
376
Qt::ShortcutContext QQuickShortcut::context()
const
377
{
378
return
m_context;
379
}
380
381
void
QQuickShortcut::setContext(Qt::ShortcutContext context)
382
{
383
if
(context == m_context)
384
return
;
385
386
ungrabShortcut(m_shortcut);
387
for
(
auto
&s : m_shortcuts)
388
ungrabShortcut(s);
389
390
m_context = context;
391
392
grabShortcut(m_shortcut, context);
393
for
(
auto
&s : m_shortcuts)
394
grabShortcut(s, context);
395
396
emit contextChanged();
397
}
398
399
void
QQuickShortcut::classBegin()
400
{
401
}
402
403
void
QQuickShortcut::componentComplete()
404
{
405
m_completed =
true
;
406
grabShortcut(m_shortcut, m_context);
407
for
(Shortcut &shortcut : m_shortcuts)
408
grabShortcut(shortcut, m_context);
409
}
410
411
bool
QQuickShortcut::event(QEvent *event)
412
{
413
if
(m_enabled && event->type() == QEvent::Shortcut) {
414
QShortcutEvent *se =
static_cast
<QShortcutEvent *>(event);
415
bool
match = m_shortcut.matches(se);
416
int
i = 0;
417
while
(!match && i < m_shortcuts.size())
418
match |= m_shortcuts.at(i++).matches(se);
419
if
(match) {
420
if
(se->isAmbiguous())
421
emit activatedAmbiguously();
422
else
423
emit activated();
424
return
true
;
425
}
426
}
427
return
false
;
428
}
429
430
bool
QQuickShortcut::Shortcut::matches(QShortcutEvent *event)
const
431
{
432
return
event->shortcutId() == id && event->key() == keySequence;
433
}
434
435
void
QQuickShortcut::setEnabled(QQuickShortcut::Shortcut &shortcut,
bool
enabled)
436
{
437
if
(shortcut.id)
438
QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enabled, shortcut.id,
this
);
439
}
440
441
void
QQuickShortcut::setAutoRepeat(QQuickShortcut::Shortcut &shortcut,
bool
repeat)
442
{
443
if
(shortcut.id)
444
QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(repeat, shortcut.id,
this
);
445
}
446
447
void
QQuickShortcut::grabShortcut(Shortcut &shortcut, Qt::ShortcutContext context)
448
{
449
if
(m_completed && !shortcut.keySequence.isEmpty()) {
450
QGuiApplicationPrivate *pApp = QGuiApplicationPrivate::instance();
451
shortcut.id = pApp->shortcutMap.addShortcut(
this
, shortcut.keySequence, context, *ctxMatcher());
452
if
(!m_enabled)
453
pApp->shortcutMap.setShortcutEnabled(
false
, shortcut.id,
this
);
454
if
(!m_autorepeat)
455
pApp->shortcutMap.setShortcutAutoRepeat(
false
, shortcut.id,
this
);
456
}
457
}
458
459
void
QQuickShortcut::ungrabShortcut(Shortcut &shortcut)
460
{
461
if
(shortcut.id) {
462
QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(shortcut.id,
this
);
463
shortcut.id = 0;
464
}
465
}
466
467
QT_END_NAMESPACE
468
469
#
include
"moc_qquickshortcut_p.cpp"
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
valueToKeySequence
static QKeySequence valueToKeySequence(const QVariant &value, const QQuickShortcut *const shortcut)
Definition
qquickshortcut.cpp:99
qQuickShortcutContextMatcher
static QT_BEGIN_NAMESPACE bool qQuickShortcutContextMatcher(QObject *obj, Qt::ShortcutContext context)
\qmltype Shortcut \nativetype QQuickShortcut \inqmlmodule QtQuick
Definition
qquickshortcut.cpp:60
ContextMatcher
bool(*) ContextMatcher(QObject *, Qt::ShortcutContext)
Definition
qquickshortcut.cpp:84
valueToKeySequences
static QList< QKeySequence > valueToKeySequences(const QVariant &value)
Definition
qquickshortcut.cpp:119
qt_quick_set_shortcut_context_matcher
Q_QUICK_EXPORT void qt_quick_set_shortcut_context_matcher(ContextMatcher matcher)
Definition
qquickshortcut.cpp:93
qtdeclarative
src
quick
util
qquickshortcut.cpp
Generated on
for Qt by
1.18.0