diff options
Diffstat (limited to 'WebKit/qt/WebCoreSupport/EditorClientQt.cpp')
-rw-r--r-- | WebKit/qt/WebCoreSupport/EditorClientQt.cpp | 251 |
1 files changed, 120 insertions, 131 deletions
diff --git a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp index 3fbc83d..534e334 100644 --- a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp @@ -346,6 +346,60 @@ void EditorClientQt::toggleGrammarChecking() notImplemented(); } +static const unsigned CtrlKey = 1 << 0; +static const unsigned AltKey = 1 << 1; +static const unsigned ShiftKey = 1 << 2; + +struct KeyDownEntry { + unsigned virtualKey; + unsigned modifiers; + const char* editorCommand; +}; + +// Handle here key down events that are needed for spatial navigation and caret browsing, or +// are not handled by QWebPage. +static const KeyDownEntry keyDownEntries[] = { + // Ones that do not have an associated QAction: + { VK_DELETE, 0, "DeleteForward" }, + { VK_BACK, ShiftKey, "DeleteBackward" }, + { VK_BACK, 0, "DeleteBackward" }, + // Ones that need special handling for caret browsing: + { VK_PRIOR, 0, "MovePageUp" }, + { VK_PRIOR, ShiftKey, "MovePageUpAndModifySelection" }, + { VK_NEXT, 0, "MovePageDown" }, + { VK_NEXT, ShiftKey, "MovePageDownAndModifySelection" }, + // Ones that need special handling for spatial navigation: + { VK_LEFT, 0, "MoveLeft" }, + { VK_RIGHT, 0, "MoveRight" }, + { VK_UP, 0, "MoveUp" }, + { VK_DOWN, 0, "MoveDown" }, +}; + +const char* editorCommandForKeyDownEvent(const KeyboardEvent* event) +{ + if (event->type() != eventNames().keydownEvent) + return ""; + + static HashMap<int, const char*> keyDownCommandsMap; + if (keyDownCommandsMap.isEmpty()) { + + unsigned numEntries = sizeof(keyDownEntries) / sizeof((keyDownEntries)[0]); + for (unsigned i = 0; i < numEntries; i++) + keyDownCommandsMap.set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].editorCommand); + } + + unsigned modifiers = 0; + if (event->shiftKey()) + modifiers |= ShiftKey; + if (event->altKey()) + modifiers |= AltKey; + if (event->ctrlKey()) + modifiers |= CtrlKey; + + int mapKey = modifiers << 16 | event->keyCode(); + return mapKey ? keyDownCommandsMap.get(mapKey) : 0; +} + void EditorClientQt::handleKeyboardEvent(KeyboardEvent* event) { Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame(); @@ -387,150 +441,85 @@ void EditorClientQt::handleKeyboardEvent(KeyboardEvent* event) return; m_page->triggerAction(action); - } else + event->setDefaultHandled(); + return; + } else { #endif // QT_NO_SHORTCUT - switch (kevent->windowsVirtualKeyCode()) { - case VK_BACK: - frame->editor()->deleteWithDirection(SelectionController::DirectionBackward, - CharacterGranularity, false, true); - break; - case VK_DELETE: - frame->editor()->deleteWithDirection(SelectionController::DirectionForward, - CharacterGranularity, false, true); - break; - case VK_LEFT: - if (kevent->shiftKey()) - frame->editor()->command("MoveLeftAndModifySelection").execute(); - else if (!frame->editor()->command("MoveLeft").execute()) - return; - break; - case VK_RIGHT: - if (kevent->shiftKey()) - frame->editor()->command("MoveRightAndModifySelection").execute(); - else if (!frame->editor()->command("MoveRight").execute()) - return; - break; - case VK_UP: - if (kevent->shiftKey()) - frame->editor()->command("MoveUpAndModifySelection").execute(); - else if (!frame->editor()->command("MoveUp").execute()) + String commandName = editorCommandForKeyDownEvent(event); + if (!commandName.isEmpty()) { + if (frame->editor()->command(commandName).execute()) // Event handled. + event->setDefaultHandled(); return; - break; - case VK_DOWN: - if (kevent->shiftKey()) - frame->editor()->command("MoveDownAndModifySelection").execute(); - else if (!frame->editor()->command("MoveDown").execute()) + } + + if (kevent->windowsVirtualKeyCode() == VK_TAB) { + // Do not handle TAB text insertion here. return; - break; - case VK_PRIOR: // PageUp - if (kevent->shiftKey()) - frame->editor()->command("MovePageUpAndModifySelection").execute(); - else - frame->editor()->command("MovePageUp").execute(); - break; - case VK_NEXT: // PageDown - if (kevent->shiftKey()) - frame->editor()->command("MovePageDownAndModifySelection").execute(); - else - frame->editor()->command("MovePageDown").execute(); - break; - case VK_TAB: - return; - default: - if (kevent->type() != PlatformKeyboardEvent::KeyDown && !kevent->ctrlKey() + } + + // Text insertion. + bool shouldInsertText = false; + if (kevent->type() != PlatformKeyboardEvent::KeyDown && !kevent->text().isEmpty()) { + + if (kevent->ctrlKey()) { + if (kevent->altKey()) + shouldInsertText = true; + } else { #ifndef Q_WS_MAC // We need to exclude checking for Alt because it is just a different Shift - && !kevent->altKey() + if (!kevent->altKey()) #endif - && !kevent->text().isEmpty()) { - frame->editor()->insertText(kevent->text(), event); - } else if (kevent->ctrlKey()) { - switch (kevent->windowsVirtualKeyCode()) { - case VK_A: - frame->editor()->command("SelectAll").execute(); - break; - case VK_B: - frame->editor()->command("ToggleBold").execute(); - break; - case VK_I: - frame->editor()->command("ToggleItalic").execute(); - break; - default: - // catch combination AltGr+key or Ctrl+Alt+key - if (kevent->type() != PlatformKeyboardEvent::KeyDown && kevent->altKey() && !kevent->text().isEmpty()) { - frame->editor()->insertText(kevent->text(), event); - break; - } - return; + shouldInsertText = true; + } - } else + } + + if (shouldInsertText) { + frame->editor()->insertText(kevent->text(), event); + event->setDefaultHandled(); return; + } } - } else { - if (m_page->handle()->page->settings()->caretBrowsingEnabled()) { - switch (kevent->windowsVirtualKeyCode()) { - case VK_LEFT: - if (kevent->shiftKey() && kevent->ctrlKey()) - frame->editor()->command("MoveWordBackwardAndModifySelection").execute(); - else if (kevent->shiftKey()) - frame->editor()->command("MoveLeftAndModifySelection").execute(); - else if (kevent->ctrlKey()) - frame->editor()->command("MoveWordBackward").execute(); - else - frame->editor()->command("MoveLeft").execute(); - break; - case VK_RIGHT: - if (kevent->shiftKey() && kevent->ctrlKey()) - frame->editor()->command("MoveWordForwardAndModifySelection").execute(); - else if (kevent->shiftKey()) - frame->editor()->command("MoveRightAndModifySelection").execute(); - else if (kevent->ctrlKey()) - frame->editor()->command("MoveWordForward").execute(); - else - frame->editor()->command("MoveRight").execute(); - break; - case VK_UP: - if (kevent->shiftKey()) - frame->editor()->command("MoveUpAndModifySelection").execute(); - else - frame->editor()->command("MoveUp").execute(); - break; - case VK_DOWN: - if (kevent->shiftKey()) - frame->editor()->command("MoveDownAndModifySelection").execute(); - else - frame->editor()->command("MoveDown").execute(); - break; - case VK_PRIOR: // PageUp - frame->editor()->command("MovePageUp").execute(); - break; - case VK_NEXT: // PageDown - frame->editor()->command("MovePageDown").execute(); - break; - case VK_HOME: - if (kevent->shiftKey()) - frame->editor()->command("MoveToBeginningOfLineAndModifySelection").execute(); - else - frame->editor()->command("MoveToBeginningOfLine").execute(); - break; - case VK_END: - if (kevent->shiftKey()) - frame->editor()->command("MoveToEndOfLineAndModifySelection").execute(); - else - frame->editor()->command("MoveToEndOfLine").execute(); - break; - default: - break; + + // Event not handled. + return; + } + + // Non editable content. + if (m_page->handle()->page->settings()->caretBrowsingEnabled()) { + switch (kevent->windowsVirtualKeyCode()) { + case VK_LEFT: + case VK_RIGHT: + case VK_UP: + case VK_DOWN: + case VK_HOME: + case VK_END: + { + QWebPage::WebAction action = QWebPagePrivate::editorActionForKeyEvent(kevent->qtEvent()); + ASSERT(action != QWebPage::NoWebAction); + m_page->triggerAction(action); + event->setDefaultHandled(); + return; + } + case VK_PRIOR: // PageUp + case VK_NEXT: // PageDown + { + String commandName = editorCommandForKeyDownEvent(event); + ASSERT(!commandName.isEmpty()); + frame->editor()->command(commandName).execute(); + event->setDefaultHandled(); + return; } } + } + #ifndef QT_NO_SHORTCUT - if (kevent->qtEvent() == QKeySequence::Copy) - m_page->triggerAction(QWebPage::Copy); - else -#endif // QT_NO_SHORTCUT - return; + if (kevent->qtEvent() == QKeySequence::Copy) { + m_page->triggerAction(QWebPage::Copy); + event->setDefaultHandled(); + return; } - event->setDefaultHandled(); +#endif // QT_NO_SHORTCUT } void EditorClientQt::handleInputMethodKeydown(KeyboardEvent*) |