| Line | Source | Count | 
| 1 |  | - | 
| 2 |  | - | 
| 3 |  | - | 
| 4 |  | - | 
| 5 |  | - | 
| 6 |  | - | 
| 7 |  | - | 
| 8 |  | - | 
| 9 |  | - | 
| 10 |  | - | 
| 11 |  | - | 
| 12 |  | - | 
| 13 |  | - | 
| 14 |  | - | 
| 15 |  | - | 
| 16 |  | - | 
| 17 |  | - | 
| 18 |  | - | 
| 19 |  | - | 
| 20 |  | - | 
| 21 |  | - | 
| 22 |  | - | 
| 23 |  | - | 
| 24 |  | - | 
| 25 |  | - | 
| 26 |  | - | 
| 27 |  | - | 
| 28 |  | - | 
| 29 |  | - | 
| 30 |  | - | 
| 31 |  | - | 
| 32 |  | - | 
| 33 |  | - | 
| 34 |  | - | 
| 35 |  | - | 
| 36 |  | - | 
| 37 |  | - | 
| 38 |  | - | 
| 39 |  | - | 
| 40 | #include "qshortcutmap_p.h" | - | 
| 41 | #include "private/qobject_p.h" | - | 
| 42 | #include "qkeysequence.h" | - | 
| 43 | #include "qdebug.h" | - | 
| 44 | #include "qevent.h" | - | 
| 45 | #include "qvector.h" | - | 
| 46 | #include "qcoreapplication.h" | - | 
| 47 | #include <private/qkeymapper_p.h> | - | 
| 48 |  | - | 
| 49 | #include <algorithm> | - | 
| 50 |  | - | 
| 51 | #ifndef QT_NO_SHORTCUT | - | 
| 52 |  | - | 
| 53 | QT_BEGIN_NAMESPACE | - | 
| 54 |  | - | 
| 55 |  | - | 
| 56 |  | - | 
| 57 |  | - | 
| 58 |  | - | 
| 59 |  | - | 
| 60 |  | - | 
| 61 |  | - | 
| 62 |  | - | 
| 63 |  | - | 
| 64 |  | - | 
| 65 | struct QShortcutEntry | - | 
| 66 | { | - | 
| 67 |     QShortcutEntry() | - | 
| 68 |         : keyseq(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0), contextMatcher(0) | - | 
| 69 |     {} | - | 
| 70 |  | - | 
| 71 |     QShortcutEntry(const QKeySequence &k) | - | 
| 72 |         : keyseq(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0), contextMatcher(0) | - | 
| 73 |     {} | - | 
| 74 |  | - | 
| 75 |     QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i, bool a, QShortcutMap::ContextMatcher m) | - | 
| 76 |         : keyseq(k), context(c), enabled(true), autorepeat(a), id(i), owner(o), contextMatcher(m) | - | 
| 77 |     {} | - | 
| 78 |  | - | 
| 79 |     bool correctContext() const { return contextMatcher(owner, context); } | - | 
| 80 |  | - | 
| 81 |     bool operator<(const QShortcutEntry &f) const | - | 
| 82 |     { return keyseq < f.keyseq; } | - | 
| 83 |  | - | 
| 84 |     QKeySequence keyseq; | - | 
| 85 |     Qt::ShortcutContext context; | - | 
| 86 |     bool enabled : 1; | - | 
| 87 |     bool autorepeat : 1; | - | 
| 88 |     signed int id; | - | 
| 89 |     QObject *owner; | - | 
| 90 |     QShortcutMap::ContextMatcher contextMatcher; | - | 
| 91 | }; | - | 
| 92 | Q_DECLARE_TYPEINFO(QShortcutEntry, Q_MOVABLE_TYPE); | - | 
| 93 |  | - | 
| 94 | #ifdef Dump_QShortcutMap | - | 
| 95 |  | - | 
| 96 |  | - | 
| 97 |  | - | 
| 98 | static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) | - | 
| 99 | { | - | 
| 100 |     QDebugStateSaver saver(dbg); | - | 
| 101 |     if (!se) | - | 
| 102 |         return dbg << "QShortcutEntry(0x0)"; | - | 
| 103 |     dbg.nospace() | - | 
| 104 |         << "QShortcutEntry(" << se->keyseq | - | 
| 105 |         << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat | - | 
| 106 |         << "), owner(" << se->owner << ')'; | - | 
| 107 |     return dbg; | - | 
| 108 | } | - | 
| 109 | #endif // Dump_QShortcutMap | - | 
| 110 |  | - | 
| 111 |  | - | 
| 112 |  | - | 
| 113 |  | - | 
| 114 | class QShortcutMapPrivate | - | 
| 115 | { | - | 
| 116 |     Q_DECLARE_PUBLIC(QShortcutMap) | - | 
| 117 |  | - | 
| 118 | public: | - | 
| 119 |     QShortcutMapPrivate(QShortcutMap* parent) | - | 
| 120 |         : q_ptr(parent), currentId(0), ambigCount(0), currentState(QKeySequence::NoMatch) | - | 
| 121 |     { | - | 
| 122 |         identicals.reserve(10); | - | 
| 123 |         currentSequences.reserve(10); | - | 
| 124 |     } | - | 
| 125 |     QShortcutMap *q_ptr;                         | - | 
| 126 |  | - | 
| 127 |     QListQVector<QShortcutEntry> sequences;           | - | 
| 128 |  | - | 
| 129 |     int currentId;                               | - | 
| 130 |     int ambigCount;                              | - | 
| 131 |     QKeySequence::SequenceMatch currentState; | - | 
| 132 |     QVector<QKeySequence> currentSequences;      | - | 
| 133 |     QVector<QKeySequence> newEntries; | - | 
| 134 |     QKeySequence prevSequence;                   | - | 
| 135 |     QVector<const QShortcutEntry*> identicals;   | - | 
| 136 | }; | - | 
| 137 |  | - | 
| 138 |  | - | 
| 139 |  | - | 
| 140 |  | - | 
| 141 |  | - | 
| 142 | QShortcutMap::QShortcutMap() | - | 
| 143 |     : d_ptr(new QShortcutMapPrivate(this)) | - | 
| 144 | { | - | 
| 145 |     resetState(); | - | 
| 146 | } | - | 
| 147 |  | - | 
| 148 |  | - | 
| 149 |  | - | 
| 150 |  | - | 
| 151 | QShortcutMap::~QShortcutMap() | - | 
| 152 | { | - | 
| 153 | } | - | 
| 154 |  | - | 
| 155 |  | - | 
| 156 |  | - | 
| 157 |  | - | 
| 158 |  | - | 
| 159 | int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context, ContextMatcher matcher) | - | 
| 160 | { | - | 
| 161 |     Q_ASSERT_X(owner, "QShortcutMap::addShortcut", "All shortcuts need an owner"); | - | 
| 162 |     Q_ASSERT_X(!key.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map"); | - | 
| 163 |     Q_D(QShortcutMap); | - | 
| 164 |  | - | 
| 165 |     QShortcutEntry newEntry(owner, key, context, --(d->currentId), true, matcher); | - | 
| 166 |     QList<QShortcutEntry>::iteratorconst auto it = std::upper_bound(d->sequences.begin(), d->sequences.end(), newEntry); | - | 
| 167 |     d->sequences.insert(it, newEntry);  | - | 
| 168 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 169 |     qDebug().nospace() | - | 
| 170 |         << "QShortcutMap::addShortcut(" << owner << ", " | - | 
| 171 |         << key << ", " << context << ") = " << d->currentId; | - | 
| 172 | #endif | - | 
| 173 |     return d->currentId; never executed: return d->currentId;  | 0 | 
| 174 | } | - | 
| 175 |  | - | 
| 176 |  | - | 
| 177 |  | - | 
| 178 |  | - | 
| 179 |  | - | 
| 180 |  | - | 
| 181 |  | - | 
| 182 |  | - | 
| 183 |  | - | 
| 184 |  | - | 
| 185 | int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key) | - | 
| 186 | { | - | 
| 187 |     Q_D(QShortcutMap); | - | 
| 188 |     int itemsRemoved = 0; | - | 
| 189 |     bool allOwners = (owner == 0); | - | 
| 190 |     bool allKeys = key.isEmpty(); | - | 
| 191 |     bool allIds = id == 0; | - | 
| 192 |  | - | 
| 193 |      | - | 
| 194 |     if (allOwners && allKeys && id == 0allIds) {| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 195 |         itemsRemoved = d->sequences.size(); | - | 
| 196 |         d->sequences.clear(); | - | 
| 197 |         return itemsRemoved; never executed: return itemsRemoved;  | 0 | 
| 198 |     } | - | 
| 199 |  | - | 
| 200 |     int i = d->sequences.size()-1; | - | 
| 201 |     while (i>=0)| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 202 |     { | - | 
| 203 |         const QShortcutEntry &entry = d->sequences.at(i); | - | 
| 204 |         int entryId = entry.id; | - | 
| 205 |         if ((allOwners || entry.owner == owner)| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 206 |             && (allIds || entry.id == id)| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 207 |             && (allKeys || entry.keyseq == key)) {| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 208 |             d->sequences.removeAt(i); | - | 
| 209 |             ++itemsRemoved; | - | 
| 210 |         } never executed: end of block  | 0 | 
| 211 |         if (id == entryId)| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 212 |             return itemsRemoved; never executed: return itemsRemoved;  | 0 | 
| 213 |         --i; | - | 
| 214 |     } never executed: end of block  | 0 | 
| 215 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 216 |     qDebug().nospace() | - | 
| 217 |         << "QShortcutMap::removeShortcut(" << id << ", " << owner << ", " | - | 
| 218 |         << key << ") = " << itemsRemoved; | - | 
| 219 | #endif | - | 
| 220 |     return itemsRemoved; never executed: return itemsRemoved;  | 0 | 
| 221 | } | - | 
| 222 |  | - | 
| 223 |  | - | 
| 224 |  | - | 
| 225 |  | - | 
| 226 |  | - | 
| 227 |  | - | 
| 228 |  | - | 
| 229 |  | - | 
| 230 |  | - | 
| 231 | int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key) | - | 
| 232 | { | - | 
| 233 |     Q_D(QShortcutMap); | - | 
| 234 |     int itemsChanged = 0; | - | 
| 235 |     bool allOwners = (owner == 0); | - | 
| 236 |     bool allKeys = key.isEmpty(); | - | 
| 237 |     bool allIds = id == 0; | - | 
| 238 |  | - | 
| 239 |     int i = d->sequences.size()-1; | - | 
| 240 |     while (i>=0) | - | 
| 241 |     { | - | 
| 242 |         QShortcutEntry entry = d->sequences.at(i); | - | 
| 243 |         if ((allOwners || entry.owner == owner) | - | 
| 244 |             && (allIds || entry.id == id) | - | 
| 245 |             && (allKeys || entry.keyseq == key)) { | - | 
| 246 |             d->sequences[i].enabled = enable; | - | 
| 247 |             ++itemsChanged; | - | 
| 248 |         } | - | 
| 249 |         if (id == entry.id) | - | 
| 250 |             return itemsChanged; | - | 
| 251 |         --i; | - | 
| 252 |     } | - | 
| 253 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 254 |     qDebug().nospace() | - | 
| 255 |         << "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", " | - | 
| 256 |         << owner << ", " << key << ") = " << itemsChanged; | - | 
| 257 | #endif | - | 
| 258 |     return itemsChanged; | - | 
| 259 | } | - | 
| 260 |  | - | 
| 261 |  | - | 
| 262 |  | - | 
| 263 |  | - | 
| 264 |  | - | 
| 265 |  | - | 
| 266 |  | - | 
| 267 |  | - | 
| 268 |  | - | 
| 269 | int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key) | - | 
| 270 | { | - | 
| 271 |     Q_D(QShortcutMap); | - | 
| 272 |     int itemsChanged = 0; | - | 
| 273 |     bool allOwners = (owner == 0); | - | 
| 274 |     bool allKeys = key.isEmpty(); | - | 
| 275 |     bool allIds = id == 0; | - | 
| 276 |  | - | 
| 277 |     int i = d->sequences.size()-1; | - | 
| 278 |     while (i>=0) | - | 
| 279 |     { | - | 
| 280 |         QShortcutEntry entry = d->sequences.at(i); | - | 
| 281 |         if ((allOwners || entry.owner == owner) | - | 
| 282 |             && (allIds || entry.id == id) | - | 
| 283 |             && (allKeys || entry.keyseq == key)) { | - | 
| 284 |                 d->sequences[i].autorepeat = on; | - | 
| 285 |                 ++itemsChanged; | - | 
| 286 |         } | - | 
| 287 |         if (id == entry.id) | - | 
| 288 |             return itemsChanged; | - | 
| 289 |         --i; | - | 
| 290 |     } | - | 
| 291 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 292 |     qDebug().nospace() | - | 
| 293 |         << "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", " | - | 
| 294 |         << owner << ", " << key << ") = " << itemsChanged; | - | 
| 295 | #endif | - | 
| 296 |     return itemsChanged; | - | 
| 297 | } | - | 
| 298 |  | - | 
| 299 |  | - | 
| 300 |  | - | 
| 301 |  | - | 
| 302 | void QShortcutMap::resetState() | - | 
| 303 | { | - | 
| 304 |     Q_D(QShortcutMap); | - | 
| 305 |     d->currentState = QKeySequence::NoMatch; | - | 
| 306 |     clearSequence(d->currentSequences); | - | 
| 307 | } | - | 
| 308 |  | - | 
| 309 |  | - | 
| 310 |  | - | 
| 311 |  | - | 
| 312 | QKeySequence::SequenceMatch QShortcutMap::state() | - | 
| 313 | { | - | 
| 314 |     Q_D(QShortcutMap); | - | 
| 315 |     return d->currentState; | - | 
| 316 | } | - | 
| 317 |  | - | 
| 318 |  | - | 
| 319 |  | - | 
| 320 |  | - | 
| 321 |  | - | 
| 322 |  | - | 
| 323 |  | - | 
| 324 |  | - | 
| 325 |  | - | 
| 326 |  | - | 
| 327 | bool QShortcutMap::tryShortcut(QKeyEvent *e) | - | 
| 328 | { | - | 
| 329 |     Q_D(QShortcutMap); | - | 
| 330 |  | - | 
| 331 |     if (e->key() == Qt::Key_unknown)| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 332 |         return false; never executed: return false;  | 0 | 
| 333 |  | - | 
| 334 |     QKeySequence::SequenceMatch previousState = state(); | - | 
| 335 |  | - | 
| 336 |     switch (nextState(e)) { | - | 
| 337 |     case QKeySequence::NoMatch: never executed: case QKeySequence::NoMatch:  | 0 | 
| 338 |          | - | 
| 339 |          | - | 
| 340 |          | - | 
| 341 |         return previousState == QKeySequence::PartialMatch; never executed: return previousState == QKeySequence::PartialMatch;  | 0 | 
| 342 |     case QKeySequence::PartialMatch: never executed: case QKeySequence::PartialMatch:  | 0 | 
| 343 |          | - | 
| 344 |          | - | 
| 345 |         return true; never executed: return true;  | 0 | 
| 346 |     case QKeySequence::ExactMatch: { never executed: case QKeySequence::ExactMatch:  | 0 | 
| 347 |          | - | 
| 348 |          | - | 
| 349 |         const int identicalMatches = d->identicals.count(); | - | 
| 350 |         resetState(); | - | 
| 351 |         dispatchEvent(e); | - | 
| 352 |          | - | 
| 353 |          | - | 
| 354 |         return identicalMatches > 0; never executed: return identicalMatches > 0;  | 0 | 
| 355 |     } | - | 
| 356 |     default:} | - | 
| 357 |     Q_UNREACHABLE(); | - | 
| 358 |     }return false; never executed: return false;  | 0 | 
| 359 | } | - | 
| 360 |  | - | 
| 361 |  | - | 
| 362 |  | - | 
| 363 |  | - | 
| 364 |  | - | 
| 365 |  | - | 
| 366 |  | - | 
| 367 | QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e) | - | 
| 368 | { | - | 
| 369 |     Q_D(QShortcutMap); | - | 
| 370 |      | - | 
| 371 |     if (e->key() >= Qt::Key_Shift &&| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 372 |         e->key() <= Qt::Key_Alt)| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 373 |         return d->currentState; never executed: return d->currentState;  | 0 | 
| 374 |  | - | 
| 375 |     QKeySequence::SequenceMatch result = QKeySequence::NoMatch; | - | 
| 376 |  | - | 
| 377 |      | - | 
| 378 |     d->identicals.resize(0);clear(); | - | 
| 379 |  | - | 
| 380 |     result = find(e); | - | 
| 381 |     if (result == QKeySequence::NoMatch && (e->modifiers() & Qt::KeypadModifier)) {| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 382 |          | - | 
| 383 |         result = find(e, Qt::KeypadModifier); | - | 
| 384 |     } never executed: end of block  | 0 | 
| 385 |     if (result == QKeySequence::NoMatch && e->modifiers() & Qt::ShiftModifier) {| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 386 |          | - | 
| 387 |         if (e->key() == Qt::Key_Backtab) {| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 388 |             QKeyEvent pe = QKeyEvent(e->type(), Qt::Key_Tab, e->modifiers(), e->text()); | - | 
| 389 |             result = find(&pe); | - | 
| 390 |         } never executed: end of block  | 0 | 
| 391 |     } never executed: end of block  | 0 | 
| 392 |  | - | 
| 393 |      | - | 
| 394 |     if (result == QKeySequence::NoMatch)| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 395 |         clearSequence(d->currentSequences); never executed: clearSequence(d->currentSequences);  | 0 | 
| 396 |     d->currentState = result; | - | 
| 397 |  | - | 
| 398 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 399 |     qDebug().nospace() << "QShortcutMap::nextState(" << e << ") = " << result; | - | 
| 400 | #endif | - | 
| 401 |     return result; never executed: return result;  | 0 | 
| 402 | } | - | 
| 403 |  | - | 
| 404 |  | - | 
| 405 |  | - | 
| 406 |  | - | 
| 407 |  | - | 
| 408 | bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const | - | 
| 409 | { | - | 
| 410 |     Q_D(const QShortcutMap); | - | 
| 411 |     QShortcutEntry entry(seq);  | - | 
| 412 |     QList<QShortcutEntry>::ConstIteratorconst auto itEnd = d->sequences.constEndcend(); | - | 
| 413 |     QList<QShortcutEntry>::ConstIteratorauto it = std::lower_bound(d->sequences.constBegincbegin(), itEnd, entry); | - | 
| 414 |  | - | 
| 415 |     for (;it != itEnd; ++it) {| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 416 |         if (matches(entry.keyseq, (*it).keyseq) == QKeySequence::ExactMatch && (*it).correctContext() && (*it).enabled) {| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 417 |             return true; never executed: return true;  | 0 | 
| 418 |         } | - | 
| 419 |     } never executed: end of block  | 0 | 
| 420 |  | - | 
| 421 |      | - | 
| 422 |     return false; never executed: return false;  | 0 | 
| 423 | } | - | 
| 424 |  | - | 
| 425 |  | - | 
| 426 |  | - | 
| 427 |  | - | 
| 428 |  | - | 
| 429 |  | - | 
| 430 |  | - | 
| 431 |  | - | 
| 432 | QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifiers) | - | 
| 433 | { | - | 
| 434 |     Q_D(QShortcutMap); | - | 
| 435 |     if (!d->sequences.count())| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 436 |         return QKeySequence::NoMatch; never executed: return QKeySequence::NoMatch;  | 0 | 
| 437 |  | - | 
| 438 |     createNewSequences(e, d->newEntries, ignoredModifiers); | - | 
| 439 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 440 |     qDebug() << "Possible shortcut key sequences:" << d->newEntries; | - | 
| 441 | #endif | - | 
| 442 |  | - | 
| 443 |      | - | 
| 444 |     if (d->newEntries == d->currentSequences) {| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 445 |         Q_ASSERT_X(e->key() != Qt::Key_unknown || e->text().length(), | - | 
| 446 |                    "QShortcutMap::find", "New sequence to find identical to previous"); | - | 
| 447 |         return QKeySequence::NoMatch; never executed: return QKeySequence::NoMatch;  | 0 | 
| 448 |     } | - | 
| 449 |  | - | 
| 450 |      | - | 
| 451 |     d->identicals.resize(0);clear(); | - | 
| 452 |  | - | 
| 453 |     bool partialFound = false; | - | 
| 454 |     bool identicalDisabledFound = false; | - | 
| 455 |     QVector<QKeySequence> okEntries; | - | 
| 456 |     int result = QKeySequence::NoMatch; | - | 
| 457 |     for (int i = d->newEntries.count()-1; i >= 0 ; --i) {| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 458 |         QShortcutEntry entry(d->newEntries.at(i));  | - | 
| 459 |         QList<QShortcutEntry>::ConstIteratorconst auto itEnd = d->sequences.constEnd(); | - | 
| 460 |         QList<QShortcutEntry>::ConstIteratorauto it = std::lower_bound(d->sequences.constBegin(), itEnd, entry); | - | 
| 461 |  | - | 
| 462 |         int oneKSResult = QKeySequence::NoMatch; | - | 
| 463 |         int tempRes = QKeySequence::NoMatch; | - | 
| 464 |         do { | - | 
| 465 |             if (it == itEnd)| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 466 |                 break; never executed: break;  | 0 | 
| 467 |             tempRes = matches(entry.keyseq, (*it).keyseq); | - | 
| 468 |             oneKSResult = qMax(oneKSResult, tempRes); | - | 
| 469 |             if (tempRes != QKeySequence::NoMatch && (*it).correctContext()) {| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 470 |                 if (tempRes == QKeySequence::ExactMatch) {| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 471 |                     if ((*it).enabled)| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 472 |                         d->identicals.append(&*it); never executed: d->identicals.append(&*it);  | 0 | 
| 473 |                     else | - | 
| 474 |                         identicalDisabledFound = true; never executed: identicalDisabledFound = true;  | 0 | 
| 475 |                 } else if (tempRes == QKeySequence::PartialMatch) {| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 476 |                      | - | 
| 477 |                     if (d->identicals.size())| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 478 |                         break; never executed: break;  | 0 | 
| 479 |                      | - | 
| 480 |                      | - | 
| 481 |                     partialFound |= (*it).enabled; | - | 
| 482 |                 } never executed: end of block  | 0 | 
| 483 |             } never executed: end of block  | 0 | 
| 484 |             ++it; | - | 
| 485 |              | - | 
| 486 |              | - | 
| 487 |              | - | 
| 488 |         } while (tempRes != QKeySequence::NoMatch); never executed: end of block | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 489 |  | - | 
| 490 |          | - | 
| 491 |          | - | 
| 492 |         if (oneKSResult > result) {| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 493 |             okEntries.clear(); | - | 
| 494 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 495 |             qDebug() << "Found better match (" << d->newEntries << "), clearing key sequence list"; | - | 
| 496 | #endif | - | 
| 497 |         } never executed: end of block  | 0 | 
| 498 |         if (oneKSResult && oneKSResult >= result) {| TRUE | never evaluated |  | FALSE | never evaluated |  
 | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 499 |             okEntries << d->newEntries.at(i); | - | 
| 500 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 501 |             qDebug() << "Added ok key sequence" << d->newEntries; | - | 
| 502 | #endif | - | 
| 503 |         } never executed: end of block  | 0 | 
| 504 |     } never executed: end of block  | 0 | 
| 505 |  | - | 
| 506 |     if (d->identicals.size()) {| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 507 |         result = QKeySequence::ExactMatch; | - | 
| 508 |     } else if (partialFound) { never executed: end of block | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 509 |         result = QKeySequence::PartialMatch; | - | 
| 510 |     } else if (identicalDisabledFound) { never executed: end of block | TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 511 |         result = QKeySequence::ExactMatch; | - | 
| 512 |     } else { never executed: end of block  | 0 | 
| 513 |         clearSequence(d->currentSequences); | - | 
| 514 |         result = QKeySequence::NoMatch; | - | 
| 515 |     } never executed: end of block  | 0 | 
| 516 |     if (result != QKeySequence::NoMatch)| TRUE | never evaluated |  | FALSE | never evaluated |  
  | 0 | 
| 517 |         d->currentSequences = okEntries; never executed: d->currentSequences = okEntries;  | 0 | 
| 518 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 519 |     qDebug() << "Returning shortcut match == " << result; | - | 
| 520 | #endif | - | 
| 521 |     return QKeySequence::SequenceMatch(result); never executed: return QKeySequence::SequenceMatch(result);  | 0 | 
| 522 | } | - | 
| 523 |  | - | 
| 524 |  | - | 
| 525 |  | - | 
| 526 |  | - | 
| 527 |  | - | 
| 528 |  | - | 
| 529 | void QShortcutMap::clearSequence(QVector<QKeySequence> &ksl) | - | 
| 530 | { | - | 
| 531 |     ksl.clear(); | - | 
| 532 |     d_func()->newEntries.clear(); | - | 
| 533 | } | - | 
| 534 |  | - | 
| 535 |  | - | 
| 536 |  | - | 
| 537 |  | - | 
| 538 |  | - | 
| 539 | void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl, int ignoredModifiers) | - | 
| 540 | { | - | 
| 541 |     Q_D(QShortcutMap); | - | 
| 542 |     QList<int> possibleKeys = QKeyMapper::possibleKeys(e); | - | 
| 543 |     int pkTotal = possibleKeys.count(); | - | 
| 544 |     if (!pkTotal) | - | 
| 545 |         return; | - | 
| 546 |  | - | 
| 547 |     int ssActual = d->currentSequences.count(); | - | 
| 548 |     int ssTotal = qMax(1, ssActual); | - | 
| 549 |      | - | 
| 550 |     ksl.resize(pkTotal * ssTotal); | - | 
| 551 |  | - | 
| 552 |     int index = ssActual ? d->currentSequences.at(0).count() : 0; | - | 
| 553 |     for (int pkNum = 0; pkNum < pkTotal; ++pkNum) { | - | 
| 554 |         for (int ssNum = 0; ssNum < ssTotal; ++ssNum) { | - | 
| 555 |             int i = (pkNum * ssTotal) + ssNum; | - | 
| 556 |             QKeySequence &curKsl = ksl[i]; | - | 
| 557 |             if (ssActual) { | - | 
| 558 |                 const QKeySequence &curSeq = d->currentSequences.at(ssNum); | - | 
| 559 |                 curKsl.setKey(curSeq[0], 0); | - | 
| 560 |                 curKsl.setKey(curSeq[1], 1); | - | 
| 561 |                 curKsl.setKey(curSeq[2], 2); | - | 
| 562 |                 curKsl.setKey(curSeq[3], 3); | - | 
| 563 |             } else { | - | 
| 564 |                 curKsl.setKey(0, 0); | - | 
| 565 |                 curKsl.setKey(0, 1); | - | 
| 566 |                 curKsl.setKey(0, 2); | - | 
| 567 |                 curKsl.setKey(0, 3); | - | 
| 568 |             } | - | 
| 569 |             curKsl.setKey(possibleKeys.at(pkNum) & ~ignoredModifiers, index); | - | 
| 570 |         } | - | 
| 571 |     } | - | 
| 572 | } | - | 
| 573 |  | - | 
| 574 |  | - | 
| 575 |  | - | 
| 576 |  | - | 
| 577 |  | - | 
| 578 |  | - | 
| 579 | QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1, | - | 
| 580 |                                                   const QKeySequence &seq2) const | - | 
| 581 | { | - | 
| 582 |     uint userN = seq1.count(), | - | 
| 583 |         seqN = seq2.count(); | - | 
| 584 |  | - | 
| 585 |     if (userN > seqN) | - | 
| 586 |         return QKeySequence::NoMatch; | - | 
| 587 |  | - | 
| 588 |      | - | 
| 589 |      | - | 
| 590 |     QKeySequence::SequenceMatch match = (userN == seqN | - | 
| 591 |                                             ? QKeySequence::ExactMatch | - | 
| 592 |                                             : QKeySequence::PartialMatch); | - | 
| 593 |  | - | 
| 594 |     for (uint i = 0; i < userN; ++i) { | - | 
| 595 |         int userKey = seq1[i], | - | 
| 596 |             sequenceKey = seq2[i]; | - | 
| 597 |         if ((userKey & Qt::Key_unknown) == Qt::Key_hyphen) | - | 
| 598 |             userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus; | - | 
| 599 |         if ((sequenceKey & Qt::Key_unknown) == Qt::Key_hyphen) | - | 
| 600 |             sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus; | - | 
| 601 |         if (userKey != sequenceKey) | - | 
| 602 |             return QKeySequence::NoMatch; | - | 
| 603 |     } | - | 
| 604 |     return match; | - | 
| 605 | } | - | 
| 606 |  | - | 
| 607 |  | - | 
| 608 |  | - | 
| 609 |  | - | 
| 610 |  | - | 
| 611 | int QShortcutMap::translateModifiers(Qt::KeyboardModifiers modifiers) | - | 
| 612 | { | - | 
| 613 |     int result = 0; | - | 
| 614 |     if (modifiers & Qt::ShiftModifier) | - | 
| 615 |         result |= Qt::SHIFT; | - | 
| 616 |     if (modifiers & Qt::ControlModifier) | - | 
| 617 |         result |= Qt::CTRL; | - | 
| 618 |     if (modifiers & Qt::MetaModifier) | - | 
| 619 |         result |= Qt::META; | - | 
| 620 |     if (modifiers & Qt::AltModifier) | - | 
| 621 |         result |= Qt::ALT; | - | 
| 622 |     return result; | - | 
| 623 | } | - | 
| 624 |  | - | 
| 625 |  | - | 
| 626 |  | - | 
| 627 |  | - | 
| 628 | QVector<const QShortcutEntry*> QShortcutMap::matches() const | - | 
| 629 | { | - | 
| 630 |     Q_D(const QShortcutMap); | - | 
| 631 |     return d->identicals; | - | 
| 632 | } | - | 
| 633 |  | - | 
| 634 |  | - | 
| 635 |  | - | 
| 636 |  | - | 
| 637 | void QShortcutMap::dispatchEvent(QKeyEvent *e) | - | 
| 638 | { | - | 
| 639 |     Q_D(QShortcutMap); | - | 
| 640 |     if (!d->identicals.size()) | - | 
| 641 |         return; | - | 
| 642 |  | - | 
| 643 |     const QKeySequence &curKey = d->identicals.at(0)->keyseq; | - | 
| 644 |     if (d->prevSequence != curKey) { | - | 
| 645 |         d->ambigCount = 0; | - | 
| 646 |         d->prevSequence = curKey; | - | 
| 647 |     } | - | 
| 648 |      | - | 
| 649 |     const QShortcutEntry *current = 0, *next = 0; | - | 
| 650 |     int i = 0, enabledShortcuts = 0; | - | 
| 651 |     while(i < d->identicals.size()) { | - | 
| 652 |         current = d->identicals.at(i); | - | 
| 653 |         if (current->enabled || !next){ | - | 
| 654 |             ++enabledShortcuts; | - | 
| 655 |             if (enabledShortcuts > d->ambigCount + 1) | - | 
| 656 |                 break; | - | 
| 657 |             next = current; | - | 
| 658 |         } | - | 
| 659 |         ++i; | - | 
| 660 |     } | - | 
| 661 |     d->ambigCount = (d->identicals.size() == i ? 0 : d->ambigCount + 1); | - | 
| 662 |      | - | 
| 663 |      | - | 
| 664 |     if (!next || (e->isAutoRepeat() && !next->autorepeat)) | - | 
| 665 |         return; | - | 
| 666 |      | - | 
| 667 | #if defined(DEBUG_QSHORTCUTMAP) | - | 
| 668 |     qDebug().nospace() | - | 
| 669 |         << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\"" | - | 
| 670 |         << next->keyseq.toString() << "\", " << next->id << ", " | - | 
| 671 |         << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')'; | - | 
| 672 | #endif | - | 
| 673 |     QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1); | - | 
| 674 |     QCoreApplication::sendEvent(const_cast<QObject *>(next->owner), &se); | - | 
| 675 | } | - | 
| 676 |  | - | 
| 677 |  | - | 
| 678 |  | - | 
| 679 |  | - | 
| 680 |  | - | 
| 681 | #if defined(Dump_QShortcutMap) | - | 
| 682 | void QShortcutMap::dumpMap() const | - | 
| 683 | { | - | 
| 684 |     Q_D(const QShortcutMap); | - | 
| 685 |     for (int i = 0; i < d->sequences.size(); ++i) | - | 
| 686 |         qDebug().nospace() << &(d->sequences.at(i)); | - | 
| 687 | } | - | 
| 688 | #endif | - | 
| 689 |  | - | 
| 690 | QT_END_NAMESPACE | - | 
| 691 |  | - | 
| 692 | #endif // QT_NO_SHORTCUT | - | 
 |  |  |