qshortcutmap.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/kernel/qshortcutmap.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qshortcutmap_p.h"-
35#include "private/qobject_p.h"-
36#include "qkeysequence.h"-
37#include "qdebug.h"-
38#include "qevent.h"-
39#include "qvector.h"-
40#include "qcoreapplication.h"-
41#include <private/qkeymapper_p.h>-
42-
43#include <algorithm>-
44-
45#ifndef QT_NO_SHORTCUT-
46-
47QT_BEGIN_NAMESPACE-
48-
49// To enable verbose output uncomment below-
50//#define DEBUG_QSHORTCUTMAP-
51-
52/* \internal-
53 Entry data for QShortcutMap-
54 Contains:-
55 Keysequence for entry-
56 Pointer to parent owning the sequence-
57*/-
58-
59struct QShortcutEntry-
60{-
61 QShortcutEntry()-
62 : keyseq(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0), contextMatcher(0)-
63 {}
never executed: end of block
0
64-
65 QShortcutEntry(const QKeySequence &k)-
66 : keyseq(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0), contextMatcher(0)-
67 {}
never executed: end of block
0
68-
69 QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i, bool a, QShortcutMap::ContextMatcher m)-
70 : keyseq(k), context(c), enabled(true), autorepeat(a), id(i), owner(o), contextMatcher(m)-
71 {}
never executed: end of block
0
72-
73 bool correctContext() const { return contextMatcher(owner, context); }
never executed: return contextMatcher(owner, context);
0
74-
75 bool operator<(const QShortcutEntry &f) const-
76 { return keyseq < f.keyseq; }
never executed: return keyseq < f.keyseq;
0
77-
78 QKeySequence keyseq;-
79 Qt::ShortcutContext context;-
80 bool enabled : 1;-
81 bool autorepeat : 1;-
82 signed int id;-
83 QObject *owner;-
84 QShortcutMap::ContextMatcher contextMatcher;-
85};-
86-
87#ifdef Dump_QShortcutMap-
88/*! \internal-
89 QDebug operator<< for easy debug output of the shortcut entries.-
90*/-
91static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se)-
92{-
93 QDebugStateSaver saver(dbg);-
94 if (!se)-
95 return dbg << "QShortcutEntry(0x0)";-
96 dbg.nospace()-
97 << "QShortcutEntry(" << se->keyseq-
98 << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat-
99 << "), owner(" << se->owner << ')';-
100 return dbg;-
101}-
102#endif // Dump_QShortcutMap-
103-
104/* \internal-
105 Private data for QShortcutMap-
106*/-
107class QShortcutMapPrivate-
108{-
109 Q_DECLARE_PUBLIC(QShortcutMap)-
110-
111public:-
112 QShortcutMapPrivate(QShortcutMap* parent)-
113 : q_ptr(parent), currentId(0), ambigCount(0), currentState(QKeySequence::NoMatch)-
114 {-
115 identicals.reserve(10);-
116 currentSequences.reserve(10);-
117 }
never executed: end of block
0
118 QShortcutMap *q_ptr; // Private's parent-
119-
120 QList<QShortcutEntry> sequences; // All sequences!-
121-
122 int currentId; // Global shortcut ID number-
123 int ambigCount; // Index of last enabled ambiguous dispatch-
124 QKeySequence::SequenceMatch currentState;-
125 QVector<QKeySequence> currentSequences; // Sequence for the current state-
126 QVector<QKeySequence> newEntries;-
127 QKeySequence prevSequence; // Sequence for the previous identical match-
128 QVector<const QShortcutEntry*> identicals; // Last identical matches-
129};-
130-
131-
132/*! \internal-
133 QShortcutMap constructor.-
134*/-
135QShortcutMap::QShortcutMap()-
136 : d_ptr(new QShortcutMapPrivate(this))-
137{-
138 resetState();-
139}
never executed: end of block
0
140-
141/*! \internal-
142 QShortcutMap destructor.-
143*/-
144QShortcutMap::~QShortcutMap()-
145{-
146}-
147-
148/*! \internal-
149 Adds a shortcut to the global map.-
150 Returns the id of the newly added shortcut.-
151*/-
152int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context, ContextMatcher matcher)-
153{-
154 Q_ASSERT_X(owner, "QShortcutMap::addShortcut", "All shortcuts need an owner");-
155 Q_ASSERT_X(!key.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map");-
156 Q_D(QShortcutMap);-
157-
158 QShortcutEntry newEntry(owner, key, context, --(d->currentId), true, matcher);-
159 QList<QShortcutEntry>::iterator it = std::upper_bound(d->sequences.begin(), d->sequences.end(), newEntry);-
160 d->sequences.insert(it, newEntry); // Insert sorted-
161#if defined(DEBUG_QSHORTCUTMAP)-
162 qDebug().nospace()-
163 << "QShortcutMap::addShortcut(" << owner << ", "-
164 << key << ", " << context << ") = " << d->currentId;-
165#endif-
166 return d->currentId;
never executed: return d->currentId;
0
167}-
168-
169/*! \internal-
170 Removes a shortcut from the global map.-
171 If \a owner is 0, all entries in the map with the key sequence specified-
172 is removed. If \a key is null, all sequences for \a owner is removed from-
173 the map. If \a id is 0, any identical \a key sequences owned by \a owner-
174 are removed.-
175 Returns the number of sequences removed from the map.-
176*/-
177-
178int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key)-
179{-
180 Q_D(QShortcutMap);-
181 int itemsRemoved = 0;-
182 bool allOwners = (owner == 0);-
183 bool allKeys = key.isEmpty();-
184 bool allIds = id == 0;-
185-
186 // Special case, remove everything-
187 if (allOwners && allKeys && id == 0) {
allOwnersDescription
TRUEnever evaluated
FALSEnever evaluated
allKeysDescription
TRUEnever evaluated
FALSEnever evaluated
id == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
188 itemsRemoved = d->sequences.size();-
189 d->sequences.clear();-
190 return itemsRemoved;
never executed: return itemsRemoved;
0
191 }-
192-
193 int i = d->sequences.size()-1;-
194 while (i>=0)
i>=0Description
TRUEnever evaluated
FALSEnever evaluated
0
195 {-
196 const QShortcutEntry &entry = d->sequences.at(i);-
197 int entryId = entry.id;-
198 if ((allOwners || entry.owner == owner)
allOwnersDescription
TRUEnever evaluated
FALSEnever evaluated
entry.owner == ownerDescription
TRUEnever evaluated
FALSEnever evaluated
0
199 && (allIds || entry.id == id)
allIdsDescription
TRUEnever evaluated
FALSEnever evaluated
entry.id == idDescription
TRUEnever evaluated
FALSEnever evaluated
0
200 && (allKeys || entry.keyseq == key)) {
allKeysDescription
TRUEnever evaluated
FALSEnever evaluated
entry.keyseq == keyDescription
TRUEnever evaluated
FALSEnever evaluated
0
201 d->sequences.removeAt(i);-
202 ++itemsRemoved;-
203 }
never executed: end of block
0
204 if (id == entryId)
id == entryIdDescription
TRUEnever evaluated
FALSEnever evaluated
0
205 return itemsRemoved;
never executed: return itemsRemoved;
0
206 --i;-
207 }
never executed: end of block
0
208#if defined(DEBUG_QSHORTCUTMAP)-
209 qDebug().nospace()-
210 << "QShortcutMap::removeShortcut(" << id << ", " << owner << ", "-
211 << key << ") = " << itemsRemoved;-
212#endif-
213 return itemsRemoved;
never executed: return itemsRemoved;
0
214}-
215-
216/*! \internal-
217 Changes the enable state of a shortcut to \a enable.-
218 If \a owner is 0, all entries in the map with the key sequence specified-
219 is removed. If \a key is null, all sequences for \a owner is removed from-
220 the map. If \a id is 0, any identical \a key sequences owned by \a owner-
221 are changed.-
222 Returns the number of sequences which are matched in the map.-
223*/-
224int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key)-
225{-
226 Q_D(QShortcutMap);-
227 int itemsChanged = 0;-
228 bool allOwners = (owner == 0);-
229 bool allKeys = key.isEmpty();-
230 bool allIds = id == 0;-
231-
232 int i = d->sequences.size()-1;-
233 while (i>=0)
i>=0Description
TRUEnever evaluated
FALSEnever evaluated
0
234 {-
235 QShortcutEntry entry = d->sequences.at(i);-
236 if ((allOwners || entry.owner == owner)
allOwnersDescription
TRUEnever evaluated
FALSEnever evaluated
entry.owner == ownerDescription
TRUEnever evaluated
FALSEnever evaluated
0
237 && (allIds || entry.id == id)
allIdsDescription
TRUEnever evaluated
FALSEnever evaluated
entry.id == idDescription
TRUEnever evaluated
FALSEnever evaluated
0
238 && (allKeys || entry.keyseq == key)) {
allKeysDescription
TRUEnever evaluated
FALSEnever evaluated
entry.keyseq == keyDescription
TRUEnever evaluated
FALSEnever evaluated
0
239 d->sequences[i].enabled = enable;-
240 ++itemsChanged;-
241 }
never executed: end of block
0
242 if (id == entry.id)
id == entry.idDescription
TRUEnever evaluated
FALSEnever evaluated
0
243 return itemsChanged;
never executed: return itemsChanged;
0
244 --i;-
245 }
never executed: end of block
0
246#if defined(DEBUG_QSHORTCUTMAP)-
247 qDebug().nospace()-
248 << "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", "-
249 << owner << ", " << key << ") = " << itemsChanged;-
250#endif-
251 return itemsChanged;
never executed: return itemsChanged;
0
252}-
253-
254/*! \internal-
255 Changes the auto repeat state of a shortcut to \a enable.-
256 If \a owner is 0, all entries in the map with the key sequence specified-
257 is removed. If \a key is null, all sequences for \a owner is removed from-
258 the map. If \a id is 0, any identical \a key sequences owned by \a owner-
259 are changed.-
260 Returns the number of sequences which are matched in the map.-
261*/-
262int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key)-
263{-
264 Q_D(QShortcutMap);-
265 int itemsChanged = 0;-
266 bool allOwners = (owner == 0);-
267 bool allKeys = key.isEmpty();-
268 bool allIds = id == 0;-
269-
270 int i = d->sequences.size()-1;-
271 while (i>=0)
i>=0Description
TRUEnever evaluated
FALSEnever evaluated
0
272 {-
273 QShortcutEntry entry = d->sequences.at(i);-
274 if ((allOwners || entry.owner == owner)
allOwnersDescription
TRUEnever evaluated
FALSEnever evaluated
entry.owner == ownerDescription
TRUEnever evaluated
FALSEnever evaluated
0
275 && (allIds || entry.id == id)
allIdsDescription
TRUEnever evaluated
FALSEnever evaluated
entry.id == idDescription
TRUEnever evaluated
FALSEnever evaluated
0
276 && (allKeys || entry.keyseq == key)) {
allKeysDescription
TRUEnever evaluated
FALSEnever evaluated
entry.keyseq == keyDescription
TRUEnever evaluated
FALSEnever evaluated
0
277 d->sequences[i].autorepeat = on;-
278 ++itemsChanged;-
279 }
never executed: end of block
0
280 if (id == entry.id)
id == entry.idDescription
TRUEnever evaluated
FALSEnever evaluated
0
281 return itemsChanged;
never executed: return itemsChanged;
0
282 --i;-
283 }
never executed: end of block
0
284#if defined(DEBUG_QSHORTCUTMAP)-
285 qDebug().nospace()-
286 << "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", "-
287 << owner << ", " << key << ") = " << itemsChanged;-
288#endif-
289 return itemsChanged;
never executed: return itemsChanged;
0
290}-
291-
292/*! \internal-
293 Resets the state of the statemachine to NoMatch-
294*/-
295void QShortcutMap::resetState()-
296{-
297 Q_D(QShortcutMap);-
298 d->currentState = QKeySequence::NoMatch;-
299 clearSequence(d->currentSequences);-
300}
never executed: end of block
0
301-
302/*! \internal-
303 Returns the current state of the statemachine-
304*/-
305QKeySequence::SequenceMatch QShortcutMap::state()-
306{-
307 Q_D(QShortcutMap);-
308 return d->currentState;
never executed: return d->currentState;
0
309}-
310-
311/*! \internal-
312 Uses nextState(QKeyEvent) to check for a grabbed shortcut.-
313-
314 If so, it is dispatched using dispatchEvent().-
315-
316 Returns true if a shortcut handled the event.-
317-
318 \sa nextState, dispatchEvent-
319*/-
320bool QShortcutMap::tryShortcut(QKeyEvent *e)-
321{-
322 Q_D(QShortcutMap);-
323-
324 if (e->key() == Qt::Key_unknown)
e->key() == Qt::Key_unknownDescription
TRUEnever evaluated
FALSEnever evaluated
0
325 return false;
never executed: return false;
0
326-
327 QKeySequence::SequenceMatch previousState = state();-
328-
329 switch (nextState(e)) {-
330 case QKeySequence::NoMatch:
never executed: case QKeySequence::NoMatch:
0
331 // In the case of going from a partial match to no match we handled the-
332 // event, since we already stated that we did for the partial match. But-
333 // in the normal case of directly going to no match we say we didn't.-
334 return previousState == QKeySequence::PartialMatch;
never executed: return previousState == QKeySequence::PartialMatch;
0
335 case QKeySequence::PartialMatch:
never executed: case QKeySequence::PartialMatch:
0
336 // For a partial match we don't know yet if we will handle the shortcut-
337 // but we need to say we did, so that we get the follow-up key-presses.-
338 return true;
never executed: return true;
0
339 case QKeySequence::ExactMatch: {
never executed: case QKeySequence::ExactMatch:
0
340 // Save number of identical matches before dispatching-
341 // to keep QShortcutMap and tryShortcut reentrant.-
342 const int identicalMatches = d->identicals.count();-
343 resetState();-
344 dispatchEvent(e);-
345 // If there are no identicals we've only found disabled shortcuts, and-
346 // shouldn't say that we handled the event.-
347 return identicalMatches > 0;
never executed: return identicalMatches > 0;
0
348 }-
349 default:
never executed: default:
0
350 Q_UNREACHABLE();-
351 }
never executed: end of block
0
352}-
353-
354/*! \internal-
355 Returns the next state of the statemachine-
356 If return value is SequenceMatch::ExactMatch, then a call to matches()-
357 will return a QObjects* list of all matching objects for the last matching-
358 sequence.-
359*/-
360QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e)-
361{-
362 Q_D(QShortcutMap);-
363 // Modifiers can NOT be shortcuts...-
364 if (e->key() >= Qt::Key_Shift &&
e->key() >= Qt::Key_ShiftDescription
TRUEnever evaluated
FALSEnever evaluated
0
365 e->key() <= Qt::Key_Alt)
e->key() <= Qt::Key_AltDescription
TRUEnever evaluated
FALSEnever evaluated
0
366 return d->currentState;
never executed: return d->currentState;
0
367-
368 QKeySequence::SequenceMatch result = QKeySequence::NoMatch;-
369-
370 // We start fresh each time..-
371 d->identicals.resize(0);-
372-
373 result = find(e);-
374 if (result == QKeySequence::NoMatch && (e->modifiers() & Qt::KeypadModifier)) {
result == QKey...uence::NoMatchDescription
TRUEnever evaluated
FALSEnever evaluated
(e->modifiers(...eypadModifier)Description
TRUEnever evaluated
FALSEnever evaluated
0
375 // Try to find a match without keypad modifier-
376 result = find(e, Qt::KeypadModifier);-
377 }
never executed: end of block
0
378 if (result == QKeySequence::NoMatch && e->modifiers() & Qt::ShiftModifier) {
result == QKey...uence::NoMatchDescription
TRUEnever evaluated
FALSEnever evaluated
e->modifiers()...:ShiftModifierDescription
TRUEnever evaluated
FALSEnever evaluated
0
379 // If Shift + Key_Backtab, also try Shift + Qt::Key_Tab-
380 if (e->key() == Qt::Key_Backtab) {
e->key() == Qt::Key_BacktabDescription
TRUEnever evaluated
FALSEnever evaluated
0
381 QKeyEvent pe = QKeyEvent(e->type(), Qt::Key_Tab, e->modifiers(), e->text());-
382 result = find(&pe);-
383 }
never executed: end of block
0
384 }
never executed: end of block
0
385-
386 // Does the new state require us to clean up?-
387 if (result == QKeySequence::NoMatch)
result == QKey...uence::NoMatchDescription
TRUEnever evaluated
FALSEnever evaluated
0
388 clearSequence(d->currentSequences);
never executed: clearSequence(d->currentSequences);
0
389 d->currentState = result;-
390-
391#if defined(DEBUG_QSHORTCUTMAP)-
392 qDebug().nospace() << "QShortcutMap::nextState(" << e << ") = " << result;-
393#endif-
394 return result;
never executed: return result;
0
395}-
396-
397-
398/*! \internal-
399 Determines if an enabled shortcut has a matcing key sequence.-
400*/-
401bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const-
402{-
403 Q_D(const QShortcutMap);-
404 QShortcutEntry entry(seq); // needed for searching-
405 QList<QShortcutEntry>::ConstIterator itEnd = d->sequences.constEnd();-
406 QList<QShortcutEntry>::ConstIterator it = std::lower_bound(d->sequences.constBegin(), itEnd, entry);-
407-
408 for (;it != itEnd; ++it) {
it != itEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
409 if (matches(entry.keyseq, (*it).keyseq) == QKeySequence::ExactMatch && (*it).correctContext() && (*it).enabled) {
matches(entry....ce::ExactMatchDescription
TRUEnever evaluated
FALSEnever evaluated
(*it).correctContext()Description
TRUEnever evaluated
FALSEnever evaluated
(*it).enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
410 return true;
never executed: return true;
0
411 }-
412 }
never executed: end of block
0
413-
414 //end of the loop: we didn't find anything-
415 return false;
never executed: return false;
0
416}-
417-
418/*! \internal-
419 Returns the next state of the statemachine, based-
420 on the new key event \a e.-
421 Matches are appended to the vector of identicals,-
422 which can be access through matches().-
423 \sa matches-
424*/-
425QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifiers)-
426{-
427 Q_D(QShortcutMap);-
428 if (!d->sequences.count())
!d->sequences.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
429 return QKeySequence::NoMatch;
never executed: return QKeySequence::NoMatch;
0
430-
431 createNewSequences(e, d->newEntries, ignoredModifiers);-
432#if defined(DEBUG_QSHORTCUTMAP)-
433 qDebug() << "Possible shortcut key sequences:" << d->newEntries;-
434#endif-
435-
436 // Should never happen-
437 if (d->newEntries == d->currentSequences) {
d->newEntries ...rrentSequencesDescription
TRUEnever evaluated
FALSEnever evaluated
0
438 Q_ASSERT_X(e->key() != Qt::Key_unknown || e->text().length(),-
439 "QShortcutMap::find", "New sequence to find identical to previous");-
440 return QKeySequence::NoMatch;
never executed: return QKeySequence::NoMatch;
0
441 }-
442-
443 // Looking for new identicals, scrap old-
444 d->identicals.resize(0);-
445-
446 bool partialFound = false;-
447 bool identicalDisabledFound = false;-
448 QVector<QKeySequence> okEntries;-
449 int result = QKeySequence::NoMatch;-
450 for (int i = d->newEntries.count()-1; i >= 0 ; --i) {
i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
451 QShortcutEntry entry(d->newEntries.at(i)); // needed for searching-
452 QList<QShortcutEntry>::ConstIterator itEnd = d->sequences.constEnd();-
453 QList<QShortcutEntry>::ConstIterator it =-
454 std::lower_bound(d->sequences.constBegin(), itEnd, entry);-
455-
456 int oneKSResult = QKeySequence::NoMatch;-
457 int tempRes = QKeySequence::NoMatch;-
458 do {-
459 if (it == itEnd)
it == itEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
460 break;
never executed: break;
0
461 tempRes = matches(entry.keyseq, (*it).keyseq);-
462 oneKSResult = qMax(oneKSResult, tempRes);-
463 if (tempRes != QKeySequence::NoMatch && (*it).correctContext()) {
tempRes != QKe...uence::NoMatchDescription
TRUEnever evaluated
FALSEnever evaluated
(*it).correctContext()Description
TRUEnever evaluated
FALSEnever evaluated
0
464 if (tempRes == QKeySequence::ExactMatch) {
tempRes == QKe...ce::ExactMatchDescription
TRUEnever evaluated
FALSEnever evaluated
0
465 if ((*it).enabled)
(*it).enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
466 d->identicals.append(&*it);
never executed: d->identicals.append(&*it);
0
467 else-
468 identicalDisabledFound = true;
never executed: identicalDisabledFound = true;
0
469 } else if (tempRes == QKeySequence::PartialMatch) {
tempRes == QKe...::PartialMatchDescription
TRUEnever evaluated
FALSEnever evaluated
0
470 // We don't need partials, if we have identicals-
471 if (d->identicals.size())
d->identicals.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
472 break;
never executed: break;
0
473 // We only care about enabled partials, so we don't consume-
474 // key events when all partials are disabled!-
475 partialFound |= (*it).enabled;-
476 }
never executed: end of block
0
477 }
never executed: end of block
0
478 ++it;-
479 // If we got a valid match on this run, there might still be more keys to check against,-
480 // so we'll loop once more. If we get NoMatch, there's guaranteed no more possible-
481 // matches in the shortcutmap.-
482 } while (tempRes != QKeySequence::NoMatch);
never executed: end of block
tempRes != QKe...uence::NoMatchDescription
TRUEnever evaluated
FALSEnever evaluated
0
483-
484 // If the type of match improves (ergo, NoMatch->Partial, or Partial->Exact), clear the-
485 // previous list. If this match is equal or better than the last match, append to the list-
486 if (oneKSResult > result) {
oneKSResult > resultDescription
TRUEnever evaluated
FALSEnever evaluated
0
487 okEntries.clear();-
488#if defined(DEBUG_QSHORTCUTMAP)-
489 qDebug() << "Found better match (" << d->newEntries << "), clearing key sequence list";-
490#endif-
491 }
never executed: end of block
0
492 if (oneKSResult && oneKSResult >= result) {
oneKSResultDescription
TRUEnever evaluated
FALSEnever evaluated
oneKSResult >= resultDescription
TRUEnever evaluated
FALSEnever evaluated
0
493 okEntries << d->newEntries.at(i);-
494#if defined(DEBUG_QSHORTCUTMAP)-
495 qDebug() << "Added ok key sequence" << d->newEntries;-
496#endif-
497 }
never executed: end of block
0
498 }
never executed: end of block
0
499-
500 if (d->identicals.size()) {
d->identicals.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
501 result = QKeySequence::ExactMatch;-
502 } else if (partialFound) {
never executed: end of block
partialFoundDescription
TRUEnever evaluated
FALSEnever evaluated
0
503 result = QKeySequence::PartialMatch;-
504 } else if (identicalDisabledFound) {
never executed: end of block
identicalDisabledFoundDescription
TRUEnever evaluated
FALSEnever evaluated
0
505 result = QKeySequence::ExactMatch;-
506 } else {
never executed: end of block
0
507 clearSequence(d->currentSequences);-
508 result = QKeySequence::NoMatch;-
509 }
never executed: end of block
0
510 if (result != QKeySequence::NoMatch)
result != QKey...uence::NoMatchDescription
TRUEnever evaluated
FALSEnever evaluated
0
511 d->currentSequences = okEntries;
never executed: d->currentSequences = okEntries;
0
512#if defined(DEBUG_QSHORTCUTMAP)-
513 qDebug() << "Returning shortcut match == " << result;-
514#endif-
515 return QKeySequence::SequenceMatch(result);
never executed: return QKeySequence::SequenceMatch(result);
0
516}-
517-
518/*! \internal-
519 Clears \a seq to an empty QKeySequence.-
520 Same as doing (the slower)-
521 \snippet code/src_gui_kernel_qshortcutmap.cpp 0-
522*/-
523void QShortcutMap::clearSequence(QVector<QKeySequence> &ksl)-
524{-
525 ksl.clear();-
526 d_func()->newEntries.clear();-
527}
never executed: end of block
0
528-
529/*! \internal-
530 Alters \a seq to the new sequence state, based on the-
531 current sequence state, and the new key event \a e.-
532*/-
533void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl, int ignoredModifiers)-
534{-
535 Q_D(QShortcutMap);-
536 QList<int> possibleKeys = QKeyMapper::possibleKeys(e);-
537 int pkTotal = possibleKeys.count();-
538 if (!pkTotal)
!pkTotalDescription
TRUEnever evaluated
FALSEnever evaluated
0
539 return;
never executed: return;
0
540-
541 int ssActual = d->currentSequences.count();-
542 int ssTotal = qMax(1, ssActual);-
543 // Resize to possible permutations of the current sequence(s).-
544 ksl.resize(pkTotal * ssTotal);-
545-
546 int index = ssActual ? d->currentSequences.at(0).count() : 0;
ssActualDescription
TRUEnever evaluated
FALSEnever evaluated
0
547 for (int pkNum = 0; pkNum < pkTotal; ++pkNum) {
pkNum < pkTotalDescription
TRUEnever evaluated
FALSEnever evaluated
0
548 for (int ssNum = 0; ssNum < ssTotal; ++ssNum) {
ssNum < ssTotalDescription
TRUEnever evaluated
FALSEnever evaluated
0
549 int i = (pkNum * ssTotal) + ssNum;-
550 QKeySequence &curKsl = ksl[i];-
551 if (ssActual) {
ssActualDescription
TRUEnever evaluated
FALSEnever evaluated
0
552 const QKeySequence &curSeq = d->currentSequences.at(ssNum);-
553 curKsl.setKey(curSeq[0], 0);-
554 curKsl.setKey(curSeq[1], 1);-
555 curKsl.setKey(curSeq[2], 2);-
556 curKsl.setKey(curSeq[3], 3);-
557 } else {
never executed: end of block
0
558 curKsl.setKey(0, 0);-
559 curKsl.setKey(0, 1);-
560 curKsl.setKey(0, 2);-
561 curKsl.setKey(0, 3);-
562 }
never executed: end of block
0
563 curKsl.setKey(possibleKeys.at(pkNum) & ~ignoredModifiers, index);-
564 }
never executed: end of block
0
565 }
never executed: end of block
0
566}
never executed: end of block
0
567-
568/*! \internal-
569 Basically the same function as QKeySequence::matches(const QKeySequence &seq) const-
570 only that is specially handles Key_hyphen as Key_Minus, as people mix these up all the time and-
571 they conceptually the same.-
572*/-
573QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1,-
574 const QKeySequence &seq2) const-
575{-
576 uint userN = seq1.count(),-
577 seqN = seq2.count();-
578-
579 if (userN > seqN)
userN > seqNDescription
TRUEnever evaluated
FALSEnever evaluated
0
580 return QKeySequence::NoMatch;
never executed: return QKeySequence::NoMatch;
0
581-
582 // If equal in length, we have a potential ExactMatch sequence,-
583 // else we already know it can only be partial.-
584 QKeySequence::SequenceMatch match = (userN == seqN
userN == seqNDescription
TRUEnever evaluated
FALSEnever evaluated
0
585 ? QKeySequence::ExactMatch-
586 : QKeySequence::PartialMatch);-
587-
588 for (uint i = 0; i < userN; ++i) {
i < userNDescription
TRUEnever evaluated
FALSEnever evaluated
0
589 int userKey = seq1[i],-
590 sequenceKey = seq2[i];-
591 if ((userKey & Qt::Key_unknown) == Qt::Key_hyphen)
(userKey & Qt:...Qt::Key_hyphenDescription
TRUEnever evaluated
FALSEnever evaluated
0
592 userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
never executed: userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
0
593 if ((sequenceKey & Qt::Key_unknown) == Qt::Key_hyphen)
(sequenceKey &...Qt::Key_hyphenDescription
TRUEnever evaluated
FALSEnever evaluated
0
594 sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
never executed: sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
0
595 if (userKey != sequenceKey)
userKey != sequenceKeyDescription
TRUEnever evaluated
FALSEnever evaluated
0
596 return QKeySequence::NoMatch;
never executed: return QKeySequence::NoMatch;
0
597 }
never executed: end of block
0
598 return match;
never executed: return match;
0
599}-
600-
601-
602/*! \internal-
603 Converts keyboard button states into modifier states-
604*/-
605int QShortcutMap::translateModifiers(Qt::KeyboardModifiers modifiers)-
606{-
607 int result = 0;-
608 if (modifiers & Qt::ShiftModifier)
modifiers & Qt::ShiftModifierDescription
TRUEnever evaluated
FALSEnever evaluated
0
609 result |= Qt::SHIFT;
never executed: result |= Qt::SHIFT;
0
610 if (modifiers & Qt::ControlModifier)
modifiers & Qt...ontrolModifierDescription
TRUEnever evaluated
FALSEnever evaluated
0
611 result |= Qt::CTRL;
never executed: result |= Qt::CTRL;
0
612 if (modifiers & Qt::MetaModifier)
modifiers & Qt::MetaModifierDescription
TRUEnever evaluated
FALSEnever evaluated
0
613 result |= Qt::META;
never executed: result |= Qt::META;
0
614 if (modifiers & Qt::AltModifier)
modifiers & Qt::AltModifierDescription
TRUEnever evaluated
FALSEnever evaluated
0
615 result |= Qt::ALT;
never executed: result |= Qt::ALT;
0
616 return result;
never executed: return result;
0
617}-
618-
619/*! \internal-
620 Returns the vector of QShortcutEntry's matching the last Identical state.-
621*/-
622QVector<const QShortcutEntry*> QShortcutMap::matches() const-
623{-
624 Q_D(const QShortcutMap);-
625 return d->identicals;
never executed: return d->identicals;
0
626}-
627-
628/*! \internal-
629 Dispatches QShortcutEvents to widgets who grabbed the matched key sequence.-
630*/-
631void QShortcutMap::dispatchEvent(QKeyEvent *e)-
632{-
633 Q_D(QShortcutMap);-
634 if (!d->identicals.size())
!d->identicals.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
635 return;
never executed: return;
0
636-
637 const QKeySequence &curKey = d->identicals.at(0)->keyseq;-
638 if (d->prevSequence != curKey) {
d->prevSequence != curKeyDescription
TRUEnever evaluated
FALSEnever evaluated
0
639 d->ambigCount = 0;-
640 d->prevSequence = curKey;-
641 }
never executed: end of block
0
642 // Find next-
643 const QShortcutEntry *current = 0, *next = 0;-
644 int i = 0, enabledShortcuts = 0;-
645 while(i < d->identicals.size()) {
i < d->identicals.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
646 current = d->identicals.at(i);-
647 if (current->enabled || !next){
current->enabledDescription
TRUEnever evaluated
FALSEnever evaluated
!nextDescription
TRUEnever evaluated
FALSEnever evaluated
0
648 ++enabledShortcuts;-
649 if (enabledShortcuts > d->ambigCount + 1)
enabledShortcu...ambigCount + 1Description
TRUEnever evaluated
FALSEnever evaluated
0
650 break;
never executed: break;
0
651 next = current;-
652 }
never executed: end of block
0
653 ++i;-
654 }
never executed: end of block
0
655 d->ambigCount = (d->identicals.size() == i ? 0 : d->ambigCount + 1);
d->identicals.size() == iDescription
TRUEnever evaluated
FALSEnever evaluated
0
656 // Don't trigger shortcut if we're autorepeating and the shortcut is-
657 // grabbed with not accepting autorepeats.-
658 if (!next || (e->isAutoRepeat() && !next->autorepeat))
!nextDescription
TRUEnever evaluated
FALSEnever evaluated
e->isAutoRepeat()Description
TRUEnever evaluated
FALSEnever evaluated
!next->autorepeatDescription
TRUEnever evaluated
FALSEnever evaluated
0
659 return;
never executed: return;
0
660 // Dispatch next enabled-
661#if defined(DEBUG_QSHORTCUTMAP)-
662 qDebug().nospace()-
663 << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\""-
664 << next->keyseq.toString() << "\", " << next->id << ", "-
665 << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')';-
666#endif-
667 QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1);-
668 QCoreApplication::sendEvent(const_cast<QObject *>(next->owner), &se);-
669}
never executed: end of block
0
670-
671/* \internal-
672 QShortcutMap dump function, only available when DEBUG_QSHORTCUTMAP is-
673 defined.-
674*/-
675#if defined(Dump_QShortcutMap)-
676void QShortcutMap::dumpMap() const-
677{-
678 Q_D(const QShortcutMap);-
679 for (int i = 0; i < d->sequences.size(); ++i)-
680 qDebug().nospace() << &(d->sequences.at(i));-
681}-
682#endif-
683-
684QT_END_NAMESPACE-
685-
686#endif // QT_NO_SHORTCUT-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9