Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qshortcutmap.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
4#include "qshortcutmap_p.h"
5#include "private/qobject_p.h"
6#include "qkeysequence.h"
7#include "qdebug.h"
8#include "qevent.h"
9#include "qlist.h"
10#include "qguiapplication.h"
11#include "qwindow.h"
12#include <private/qkeymapper_p.h>
13#include <QtCore/qloggingcategory.h>
14#include <QtCore/qscopeguard.h>
15
16#include <algorithm>
17
19
20Q_LOGGING_CATEGORY(lcShortcutMap, "qt.gui.shortcutmap")
21
22/* \internal
23 Entry data for QShortcutMap
24 Contains:
25 Keysequence for entry
26 Pointer to parent owning the sequence
27*/
28
30{
32 : keyseq(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(nullptr), contextMatcher(nullptr)
33 {}
34
36 : keyseq(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(nullptr), contextMatcher(nullptr)
37 {}
38
40 : keyseq(k), context(c), enabled(true), autorepeat(a), id(i), owner(o), contextMatcher(m)
41 {}
42
43 bool correctContext() const { return contextMatcher(owner, context); }
44
45 bool operator<(const QShortcutEntry &f) const
46 { return keyseq < f.keyseq; }
47
50 bool enabled : 1;
51 bool autorepeat : 1;
52 signed int id;
55};
57
58#ifdef Dump_QShortcutMap
62static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se)
63{
64 QDebugStateSaver saver(dbg);
65 if (!se)
66 return dbg << "QShortcutEntry(0x0)";
67 dbg.nospace()
68 << "QShortcutEntry(" << se->keyseq
69 << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat
70 << "), owner(" << se->owner << ')';
71 return dbg;
72}
73#endif // Dump_QShortcutMap
74
75/* \internal
76 Private data for QShortcutMap
77*/
79{
80 Q_DECLARE_PUBLIC(QShortcutMap)
81
82public:
85 {
88 }
89 QShortcutMap *q_ptr; // Private's parent
90
92
93 int currentId; // Global shortcut ID number
94 int ambigCount; // Index of last enabled ambiguous dispatch
96 QList<QKeySequence> currentSequences; // Sequence for the current state
98 QKeySequence prevSequence; // Sequence for the previous identical match
99 QList<const QShortcutEntry*> identicals; // Last identical matches
100};
101
102
107 : d_ptr(new QShortcutMapPrivate(this))
108{
109 resetState();
110}
111
116{
117}
118
124{
125 Q_ASSERT_X(owner, "QShortcutMap::addShortcut", "All shortcuts need an owner");
126 Q_ASSERT_X(!key.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map");
127 Q_D(QShortcutMap);
128
129 QShortcutEntry newEntry(owner, key, context, --(d->currentId), true, matcher);
130 const auto it = std::upper_bound(d->sequences.begin(), d->sequences.end(), newEntry);
131 d->sequences.insert(it, newEntry); // Insert sorted
132 qCDebug(lcShortcutMap).nospace()
133 << "QShortcutMap::addShortcut(" << owner << ", "
134 << key << ", " << context << ") added shortcut with ID " << d->currentId;
135 return d->currentId;
136}
137
148{
149 Q_D(QShortcutMap);
150 int itemsRemoved = 0;
151 bool allOwners = (owner == nullptr);
152 bool allKeys = key.isEmpty();
153 bool allIds = id == 0;
154
155 auto debug = qScopeGuard([&](){
156 qCDebug(lcShortcutMap).nospace()
157 << "QShortcutMap::removeShortcut(" << id << ", " << owner << ", "
158 << key << ") removed " << itemsRemoved << " shortcuts(s)";
159 });
160
161 // Special case, remove everything
162 if (allOwners && allKeys && allIds) {
163 itemsRemoved = d->sequences.size();
164 d->sequences.clear();
165 return itemsRemoved;
166 }
167
168 int i = d->sequences.size()-1;
169 while (i>=0)
170 {
171 const QShortcutEntry &entry = d->sequences.at(i);
172 int entryId = entry.id;
173 if ((allOwners || entry.owner == owner)
174 && (allIds || entry.id == id)
175 && (allKeys || entry.keyseq == key)) {
176 d->sequences.removeAt(i);
177 ++itemsRemoved;
178 }
179 if (id == entryId)
180 return itemsRemoved;
181 --i;
182 }
183 return itemsRemoved;
184}
185
195{
196 Q_D(QShortcutMap);
197 int itemsChanged = 0;
198 bool allOwners = (owner == nullptr);
199 bool allKeys = key.isEmpty();
200 bool allIds = id == 0;
201
202 int i = d->sequences.size()-1;
203 while (i>=0)
204 {
205 QShortcutEntry entry = d->sequences.at(i);
206 if ((allOwners || entry.owner == owner)
207 && (allIds || entry.id == id)
208 && (allKeys || entry.keyseq == key)) {
209 d->sequences[i].enabled = enable;
210 ++itemsChanged;
211 }
212 if (id == entry.id)
213 return itemsChanged;
214 --i;
215 }
216 qCDebug(lcShortcutMap).nospace()
217 << "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", "
218 << owner << ", " << key << ") = " << itemsChanged;
219 return itemsChanged;
220}
221
231{
232 Q_D(QShortcutMap);
233 int itemsChanged = 0;
234 bool allOwners = (owner == nullptr);
235 bool allKeys = key.isEmpty();
236 bool allIds = id == 0;
237
238 int i = d->sequences.size()-1;
239 while (i>=0)
240 {
241 QShortcutEntry entry = d->sequences.at(i);
242 if ((allOwners || entry.owner == owner)
243 && (allIds || entry.id == id)
244 && (allKeys || entry.keyseq == key)) {
245 d->sequences[i].autorepeat = on;
246 ++itemsChanged;
247 }
248 if (id == entry.id)
249 return itemsChanged;
250 --i;
251 }
252 qCDebug(lcShortcutMap).nospace()
253 << "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", "
254 << owner << ", " << key << ") = " << itemsChanged;
255 return itemsChanged;
256}
257
261void QShortcutMap::resetState()
262{
263 Q_D(QShortcutMap);
264 d->currentState = QKeySequence::NoMatch;
265 clearSequence(d->currentSequences);
266}
267
272{
273 Q_D(QShortcutMap);
274 return d->currentState;
275}
276
287{
288 Q_D(QShortcutMap);
289
290 if (e->key() == Qt::Key_unknown)
291 return false;
292
293 QKeySequence::SequenceMatch previousState = state();
294
295 switch (nextState(e)) {
297 // In the case of going from a partial match to no match we handled the
298 // event, since we already stated that we did for the partial match. But
299 // in the normal case of directly going to no match we say we didn't.
300 return previousState == QKeySequence::PartialMatch;
302 // For a partial match we don't know yet if we will handle the shortcut
303 // but we need to say we did, so that we get the follow-up key-presses.
304 return true;
306 // Save number of identical matches before dispatching
307 // to keep QShortcutMap and tryShortcut reentrant.
308 const int identicalMatches = d->identicals.size();
309 resetState();
310 dispatchEvent(e);
311 // If there are no identicals we've only found disabled shortcuts, and
312 // shouldn't say that we handled the event.
313 return identicalMatches > 0;
314 }
315 }
316 Q_UNREACHABLE_RETURN(false);
317}
318
325QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e)
326{
327 Q_D(QShortcutMap);
328 // Modifiers can NOT be shortcuts...
329 if (e->key() >= Qt::Key_Shift &&
330 e->key() <= Qt::Key_ScrollLock)
331 return d->currentState;
332
334
335 // We start fresh each time..
336 d->identicals.clear();
337
338 result = find(e);
339 if (result == QKeySequence::NoMatch && (e->modifiers() & Qt::KeypadModifier)) {
340 // Try to find a match without keypad modifier
341 result = find(e, Qt::KeypadModifier);
342 }
343 if (result == QKeySequence::NoMatch && e->modifiers() & Qt::ShiftModifier) {
344 // If Shift + Key_Backtab, also try Shift + Qt::Key_Tab
345 if (e->key() == Qt::Key_Backtab) {
346 QKeyEvent pe = QKeyEvent(e->type(), Qt::Key_Tab, e->modifiers(), e->text());
347 result = find(&pe);
348 }
349 }
350
351 // Does the new state require us to clean up?
353 clearSequence(d->currentSequences);
354 d->currentState = result;
355
356 qCDebug(lcShortcutMap).nospace() << "QShortcutMap::nextState(" << e << ") = " << result;
357 return result;
358}
359
360
365{
366 Q_D(const QShortcutMap);
367 QShortcutEntry entry(seq); // needed for searching
368 const auto itEnd = d->sequences.cend();
369 auto it = std::lower_bound(d->sequences.cbegin(), itEnd, entry);
370
371 for (;it != itEnd; ++it) {
372 if (matches(entry.keyseq, (*it).keyseq) == QKeySequence::ExactMatch && (*it).correctContext() && (*it).enabled) {
373 return true;
374 }
375 }
376
377 //end of the loop: we didn't find anything
378 return false;
379}
380
388QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifiers)
389{
390 Q_D(QShortcutMap);
391 if (!d->sequences.size())
393
394 createNewSequences(e, d->newEntries, ignoredModifiers);
395 qCDebug(lcShortcutMap) << "Possible shortcut key sequences:" << d->newEntries;
396
397 // Should never happen
398 if (d->newEntries == d->currentSequences) {
399 Q_ASSERT_X(e->key() != Qt::Key_unknown || e->text().size(),
400 "QShortcutMap::find", "New sequence to find identical to previous");
402 }
403
404 // Looking for new identicals, scrap old
405 d->identicals.clear();
406
407 bool partialFound = false;
408 bool identicalDisabledFound = false;
409 QList<QKeySequence> okEntries;
411 for (int i = d->newEntries.size()-1; i >= 0 ; --i) {
412 QShortcutEntry entry(d->newEntries.at(i)); // needed for searching
413 qCDebug(lcShortcutMap) << "- checking entry" << entry.id << entry.keyseq;
414 const auto itEnd = d->sequences.constEnd();
415 auto it = std::lower_bound(d->sequences.constBegin(), itEnd, entry);
416
417 int oneKSResult = QKeySequence::NoMatch;
418 int tempRes = QKeySequence::NoMatch;
419 do {
420 if (it == itEnd)
421 break;
422 tempRes = matches(entry.keyseq, (*it).keyseq);
423 oneKSResult = qMax(oneKSResult, tempRes);
424 qCDebug(lcShortcutMap) << " - matches returned" << tempRes << "for" << entry.keyseq << it->keyseq
425 << "- correctContext()?" << it->correctContext();
426 if (tempRes != QKeySequence::NoMatch && (*it).correctContext()) {
427 if (tempRes == QKeySequence::ExactMatch) {
428 if ((*it).enabled)
429 d->identicals.append(&*it);
430 else
431 identicalDisabledFound = true;
432 } else if (tempRes == QKeySequence::PartialMatch) {
433 // We don't need partials, if we have identicals
434 if (d->identicals.size())
435 break;
436 // We only care about enabled partials, so we don't consume
437 // key events when all partials are disabled!
438 partialFound |= (*it).enabled;
439 }
440 }
441 ++it;
442 // If we got a valid match on this run, there might still be more keys to check against,
443 // so we'll loop once more. If we get NoMatch, there's guaranteed no more possible
444 // matches in the shortcutmap.
445 } while (tempRes != QKeySequence::NoMatch);
446
447 // If the type of match improves (ergo, NoMatch->Partial, or Partial->Exact), clear the
448 // previous list. If this match is equal or better than the last match, append to the list
449 if (oneKSResult > result) {
450 okEntries.clear();
451 qCDebug(lcShortcutMap) << "Found better match (" << d->newEntries << "), clearing key sequence list";
452 }
453 if (oneKSResult && oneKSResult >= result) {
454 okEntries << d->newEntries.at(i);
455 qCDebug(lcShortcutMap) << "Added ok key sequence" << d->newEntries;
456 }
457 }
458
459 if (d->identicals.size()) {
461 } else if (partialFound) {
463 } else if (identicalDisabledFound) {
465 } else {
466 clearSequence(d->currentSequences);
468 }
470 d->currentSequences = okEntries;
471 qCDebug(lcShortcutMap) << "Returning shortcut match == " << result;
473}
474
480void QShortcutMap::clearSequence(QList<QKeySequence> &ksl)
481{
482 ksl.clear();
483 d_func()->newEntries.clear();
484}
485
490void QShortcutMap::createNewSequences(QKeyEvent *e, QList<QKeySequence> &ksl, int ignoredModifiers)
491{
492 Q_D(QShortcutMap);
493 QList<int> possibleKeys = QKeyMapper::possibleKeys(e);
494 qCDebug(lcShortcutMap) << "Creating new sequences for" << e
495 << "with ignoredModifiers=" << Qt::KeyboardModifiers(ignoredModifiers);
496 int pkTotal = possibleKeys.size();
497 if (!pkTotal)
498 return;
499
500 int ssActual = d->currentSequences.size();
501 int ssTotal = qMax(1, ssActual);
502 // Resize to possible permutations of the current sequence(s).
503 ksl.resize(pkTotal * ssTotal);
504
505 int index = ssActual ? d->currentSequences.at(0).count() : 0;
506 for (int pkNum = 0; pkNum < pkTotal; ++pkNum) {
507 for (int ssNum = 0; ssNum < ssTotal; ++ssNum) {
508 int i = (pkNum * ssTotal) + ssNum;
509 QKeySequence &curKsl = ksl[i];
510 if (ssActual) {
511 const QKeySequence &curSeq = d->currentSequences.at(ssNum);
512 curKsl.setKey(curSeq[0], 0);
513 curKsl.setKey(curSeq[1], 1);
514 curKsl.setKey(curSeq[2], 2);
515 curKsl.setKey(curSeq[3], 3);
516 } else {
517 curKsl.setKey(QKeyCombination::fromCombined(0), 0);
518 curKsl.setKey(QKeyCombination::fromCombined(0), 1);
519 curKsl.setKey(QKeyCombination::fromCombined(0), 2);
520 curKsl.setKey(QKeyCombination::fromCombined(0), 3);
521 }
522 curKsl.setKey(QKeyCombination::fromCombined(possibleKeys.at(pkNum) & ~ignoredModifiers), index);
523 }
524 }
525}
526
532QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1,
533 const QKeySequence &seq2) const
534{
535 uint userN = seq1.count(),
536 seqN = seq2.count();
537
538 if (userN > seqN)
540
541 // If equal in length, we have a potential ExactMatch sequence,
542 // else we already know it can only be partial.
543 QKeySequence::SequenceMatch match = (userN == seqN
546
547 for (uint i = 0; i < userN; ++i) {
548 int userKey = seq1[i].toCombined(),
549 sequenceKey = seq2[i].toCombined();
550 if ((userKey & Qt::Key_unknown) == Qt::Key_hyphen)
551 userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
552 if ((sequenceKey & Qt::Key_unknown) == Qt::Key_hyphen)
553 sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
554 if (userKey != sequenceKey)
556 }
557 return match;
558}
559
560
564int QShortcutMap::translateModifiers(Qt::KeyboardModifiers modifiers)
565{
566 int result = 0;
568 result |= Qt::SHIFT;
570 result |= Qt::CTRL;
572 result |= Qt::META;
574 result |= Qt::ALT;
575 return result;
576}
577
581QList<const QShortcutEntry*> QShortcutMap::matches() const
582{
583 Q_D(const QShortcutMap);
584 return d->identicals;
585}
586
590void QShortcutMap::dispatchEvent(QKeyEvent *e)
591{
592 Q_D(QShortcutMap);
593 if (!d->identicals.size())
594 return;
595
596 const QKeySequence &curKey = d->identicals.at(0)->keyseq;
597 if (d->prevSequence != curKey) {
598 d->ambigCount = 0;
599 d->prevSequence = curKey;
600 }
601 // Find next
602 const QShortcutEntry *current = nullptr, *next = nullptr;
603 int i = 0, enabledShortcuts = 0;
604 QList<const QShortcutEntry*> ambiguousShortcuts;
605 while(i < d->identicals.size()) {
606 current = d->identicals.at(i);
607 if (current->enabled || !next){
608 ++enabledShortcuts;
609 if (lcShortcutMap().isDebugEnabled())
610 ambiguousShortcuts.append(current);
611 if (enabledShortcuts > d->ambigCount + 1)
612 break;
613 next = current;
614 }
615 ++i;
616 }
617 d->ambigCount = (d->identicals.size() == i ? 0 : d->ambigCount + 1);
618 // Don't trigger shortcut if we're autorepeating and the shortcut is
619 // grabbed with not accepting autorepeats.
620 if (!next || (e->isAutoRepeat() && !next->autorepeat))
621 return;
622 // Dispatch next enabled
623 if (lcShortcutMap().isDebugEnabled()) {
624 if (ambiguousShortcuts.size() > 1) {
625 qCDebug(lcShortcutMap) << "The following shortcuts are about to be activated ambiguously:";
626 for (const QShortcutEntry *entry : std::as_const(ambiguousShortcuts))
627 qCDebug(lcShortcutMap).nospace() << "- " << entry->keyseq << " (belonging to " << entry->owner << ")";
628 }
629
630 qCDebug(lcShortcutMap).nospace()
631 << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\""
632 << next->keyseq.toString() << "\", " << next->id << ", "
633 << static_cast<bool>(enabledShortcuts>1) << ") to object(" << next->owner << ')';
634 }
635 QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1);
636 QCoreApplication::sendEvent(const_cast<QObject *>(next->owner), &se);
637}
638
640{
641 Q_D(const QShortcutMap);
643 for (auto sequence : d->sequences) {
644 bool addSequence = false;
645 if (sequence.enabled) {
646 if (getAll || sequence.context == Qt::ApplicationShortcut ||
647 sequence.owner == QGuiApplication::focusObject()) {
648 addSequence = true;
649 } else {
650 QObject *possibleWindow = sequence.owner;
651 while (possibleWindow) {
652 if (qobject_cast<QWindow *>(possibleWindow))
653 break;
654 possibleWindow = possibleWindow->parent();
655 }
656 if (possibleWindow == QGuiApplication::focusWindow()) {
657 if (sequence.context == Qt::WindowShortcut) {
658 addSequence = true;
659 } else if (sequence.context == Qt::WidgetWithChildrenShortcut) {
660 QObject *possibleWidget = QGuiApplication::focusObject();
661 while (possibleWidget->parent()) {
662 possibleWidget = possibleWidget->parent();
663 if (possibleWidget == sequence.owner) {
664 addSequence = true;
665 break;
666 }
667 }
668 }
669 }
670 }
671 if (addSequence)
672 keys << sequence.keyseq;
673 }
674 }
675 return keys;
676
677}
678
679/* \internal
680 QShortcutMap dump function, only available when DEBUG_QSHORTCUTMAP is
681 defined.
682*/
683#if defined(Dump_QShortcutMap)
684void QShortcutMap::dumpMap() const
685{
686 Q_D(const QShortcutMap);
687 for (int i = 0; i < d->sequences.size(); ++i)
688 qDebug().nospace() << &(d->sequences.at(i));
689}
690#endif
691
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
\inmodule QtCore
\inmodule QtCore
static QObject * focusObject()
Returns the QObject in currently active window that will be final receiver of events tied to focus,...
static QWindow * focusWindow()
Returns the QWindow that receives events tied to focus, such as key events.
static constexpr QKeyCombination fromCombined(int combined)
The QKeyEvent class describes a key event.
Definition qevent.h:423
static QList< int > possibleKeys(QKeyEvent *e)
The QKeySequence class encapsulates a key sequence as used by shortcuts.
SequenceMatch
\value NoMatch The key sequences are different; not even partially matching.
int count() const
Returns the number of keys in the key sequence.
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void reserve(qsizetype size)
Definition qlist.h:746
void resize(qsizetype size)
Definition qlist.h:392
void append(parameter_type t)
Definition qlist.h:441
void clear()
Definition qlist.h:417
\inmodule QtCore
Definition qobject.h:90
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
The QShortcutEvent class provides an event which is generated when the user presses a key combination...
QShortcutMap * q_ptr
QList< QShortcutEntry > sequences
QList< QKeySequence > newEntries
QKeySequence prevSequence
QList< const QShortcutEntry * > identicals
QList< QKeySequence > currentSequences
QShortcutMapPrivate(QShortcutMap *parent)
QKeySequence::SequenceMatch currentState
bool hasShortcutForKeySequence(const QKeySequence &seq) const
int setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key=QKeySequence())
int removeShortcut(int id, QObject *owner, const QKeySequence &key=QKeySequence())
int setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key=QKeySequence())
int addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context, ContextMatcher matcher)
bool tryShortcut(QKeyEvent *e)
QList< QKeySequence > keySequences(bool getAll=false) const
QKeySequence::SequenceMatch state()
bool(* ContextMatcher)(QObject *object, Qt::ShortcutContext context)
EGLImageKHR int int EGLuint64KHR * modifiers
#define this
Definition dialogs.cpp:9
double e
QSet< QString >::iterator it
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
@ CTRL
@ META
@ SHIFT
@ ALT
@ Key_Tab
Definition qnamespace.h:659
@ Key_Shift
Definition qnamespace.h:678
@ Key_Backtab
Definition qnamespace.h:660
@ Key_hyphen
Definition qnamespace.h:597
@ Key_Minus
Definition qnamespace.h:526
@ Key_ScrollLock
Definition qnamespace.h:684
@ Key_unknown
@ ShiftModifier
@ ControlModifier
@ MetaModifier
@ KeypadModifier
@ KeyboardModifierMask
@ AltModifier
ShortcutContext
@ WidgetWithChildrenShortcut
@ WindowShortcut
@ ApplicationShortcut
static void * context
#define qDebug
[1]
Definition qlogging.h:160
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
const GLfloat * m
GLuint64 key
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLenum GLuint id
[7]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
GLboolean enable
const GLubyte * c
GLuint entry
GLuint64EXT * result
[6]
bool(* ContextMatcher)(QObject *, Qt::ShortcutContext)
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
static void allKeys(HKEY parentHandle, const QString &rSubKey, NameSet *result, REGSAM access=0)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:145
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:163
unsigned int uint
Definition qtypes.h:29
QWindow * qobject_cast< QWindow * >(QObject *o)
Definition qwindow.h:367
QStringList keys
QDataStream & operator<<(QDataStream &out, const MyClass &myObj)
[4]
QObject::connect nullptr
static const auto matcher
[0]
QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i, bool a, QShortcutMap::ContextMatcher m)
bool correctContext() const
QShortcutEntry(const QKeySequence &k)
Qt::ShortcutContext context
QShortcutMap::ContextMatcher contextMatcher
QKeySequence keyseq
bool operator<(const QShortcutEntry &f) const
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent