void KMenu::keyPressEvent(QKeyEvent* e) { d->mouseButtons = Qt::NoButton; d->keyboardModifiers = Qt::NoModifier; if (!d->shortcuts) { d->keyboardModifiers = e->modifiers(); QMenu::keyPressEvent(e); if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down) { d->skipTitles(e); } return; } QAction* a = 0L; bool firstpass = true; QString keyString = e->text(); // check for common commands dealt with by QMenu int key = e->key(); if (key == Qt::Key_Escape || key == Qt::Key_Return || key == Qt::Key_Enter || key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_Left || key == Qt::Key_Right || key == Qt::Key_F1 || key == Qt::Key_PageUp || key == Qt::Key_PageDown || key == Qt::Key_Back || key == Qt::Key_Select) { d->resetKeyboardVars(); // continue event processing by QMenu //e->ignore(); d->keyboardModifiers = e->modifiers(); QMenu::keyPressEvent(e); if (key == Qt::Key_Up || key == Qt::Key_Down) { d->skipTitles(e); } return; } else if ( key == Qt::Key_Shift || key == Qt::Key_Control || key == Qt::Key_Alt || key == Qt::Key_Meta ) return QMenu::keyPressEvent(e); // check to see if the user wants to remove a key from the sequence (backspace) // or clear the sequence (delete) if (!d->keySeq.isNull()) { if (key == Qt::Key_Backspace) { if (d->keySeq.length() == 1) { d->resetKeyboardVars(); return; } // keep the last sequence in keyString keyString = d->keySeq.left(d->keySeq.length() - 1); // allow sequence matching to be tried again d->resetKeyboardVars(); } else if (key == Qt::Key_Delete) { d->resetKeyboardVars(); // clear active item setActiveAction(0L); return; } else if (d->noMatches) { // clear if there are no matches d->resetKeyboardVars(); // clear active item setActiveAction(0L); } else { // the key sequence is not a null string // therefore the lastHitAction is valid a = d->lastHitAction; } } else if (key == Qt::Key_Backspace && menuAction()) { // backspace with no chars in the buffer... go back a menu. hide(); d->resetKeyboardVars(); return; } d->keySeq += keyString; const int seqLen = d->keySeq.length(); foreach (a, actions()) { // don't search disabled entries if (!a->isEnabled()) continue; QString thisText; // retrieve the right text // (the last selected item one may have additional ampersands) if (a == d->lastHitAction) thisText = d->originalText; else thisText = a->text(); // if there is an accelerator present, remove it thisText = KGlobal::locale()->removeAcceleratorMarker(thisText); // chop text to the search length thisText = thisText.left(seqLen); // do the search if (!thisText.indexOf(d->keySeq, 0, Qt::CaseInsensitive)) { if (firstpass) { // match setActiveAction(a); // check to see if we're underlining a different item if (d->lastHitAction && d->lastHitAction != a) // yes; revert the underlining d->lastHitAction->setText(d->originalText); // set the original text if it's a different item if (d->lastHitAction != a || d->lastHitAction == 0L) d->originalText = a->text(); // underline the currently selected item a->setText(underlineText(d->originalText, d->keySeq.length())); // remember what's going on d->lastHitAction = a; // start/restart the clear timer d->clearTimer.setSingleShot(true); d->clearTimer.start(5000); // go around for another try, to see if we can execute firstpass = false; } else { // don't allow execution return; } } // fall through to allow execution } if (!firstpass) { if (d->autoExec) { // activate anything d->lastHitAction->activate(QAction::Trigger); d->resetKeyboardVars(); } else if (d->lastHitAction && d->lastHitAction->menu()) { // only activate sub-menus d->lastHitAction->activate(QAction::Trigger); d->resetKeyboardVars(); } return; } // no matches whatsoever, clean up d->resetKeyboardVars(true); //e->ignore(); QMenu::keyPressEvent(e); }
void KPopupMenu::keyPressEvent(QKeyEvent* e) { if (!d->shortcuts) { // continue event processing by Qpopup //e->ignore(); QPopupMenu::keyPressEvent(e); return; } int i = 0; bool firstpass = true; QString keyString = e->text(); // check for common commands dealt with by QPopup int key = e->key(); if (key == Key_Escape || key == Key_Return || key == Key_Enter || key == Key_Up || key == Key_Down || key == Key_Left || key == Key_Right || key == Key_F1) { resetKeyboardVars(); // continue event processing by Qpopup //e->ignore(); QPopupMenu::keyPressEvent(e); return; } // check to see if the user wants to remove a key from the sequence (backspace) // or clear the sequence (delete) if (d->keySeq != QString::null) { if (key == Key_Backspace) { if (d->keySeq.length() == 1) { resetKeyboardVars(); return; } // keep the last sequence in keyString keyString = d->keySeq.left(d->keySeq.length() - 1); // allow sequence matching to be tried again resetKeyboardVars(); } else if (key == Key_Delete) { resetKeyboardVars(); // clear active item setActiveItem(0); return; } else if (d->noMatches) { // clear if there are no matches resetKeyboardVars(); // clear active item setActiveItem(0); } else { // the key sequence is not a null string // therefore the lastHitIndex is valid i = d->lastHitIndex; } } else if (key == Key_Backspace && parentMenu) { // backspace with no chars in the buffer... go back a menu. hide(); resetKeyboardVars(); return; } d->keySeq += keyString; int seqLen = d->keySeq.length(); for (; i < (int)count(); i++) { // compare typed text with text of this entry int j = idAt(i); // don't search disabled entries if (!isItemEnabled(j)) continue; QString thisText; // retrieve the right text // (the last selected item one may have additional ampersands) if (i == d->lastHitIndex) thisText = d->originalText; else thisText = text(j); // if there is an accelerator present, remove it if ((int)accel(j) != 0) thisText = thisText.replace(QRegExp("&"), ""); // chop text to the search length thisText = thisText.left(seqLen); // do the search if (thisText.find(d->keySeq, 0, false) == 0) { if (firstpass) { // match setActiveItem(i); // check to see if we're underlining a different item if (d->lastHitIndex != i) // yes; revert the underlining changeItem(idAt(d->lastHitIndex), d->originalText); // set the original text if it's a different item if (d->lastHitIndex != i || d->lastHitIndex == -1) d->originalText = text(j); // underline the currently selected item changeItem(j, underlineText(d->originalText, d->keySeq.length())); // remeber what's going on d->lastHitIndex = i; // start/restart the clear timer d->clearTimer.start(5000, true); // go around for another try, to see if we can execute firstpass = false; } else { // don't allow execution return; } } // fall through to allow execution } if (!firstpass) { if (d->autoExec) { // activate anything activateItemAt(d->lastHitIndex); resetKeyboardVars(); } else if (findItem(idAt(d->lastHitIndex)) && findItem(idAt(d->lastHitIndex))->popup()) { // only activate sub-menus activateItemAt(d->lastHitIndex); resetKeyboardVars(); } return; } // no matches whatsoever, clean up resetKeyboardVars(true); //e->ignore(); QPopupMenu::keyPressEvent(e); }