2 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "EditorClientGtk.h"
22 #include "EditCommand.h"
24 #include "FocusController.h"
26 #include "KeyboardCodes.h"
27 #include "KeyboardEvent.h"
28 #include "NotImplemented.h"
30 #include "PlatformKeyboardEvent.h"
31 #include "webkitprivate.h"
33 using namespace WebCore;
37 static void imContextCommitted(GtkIMContext* context, const char* str, EditorClient* client)
39 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(client->m_webView);
40 Frame* frame = webViewData->corePage->focusController()->focusedOrMainFrame();
41 frame->editor()->insertTextWithoutSendingTextEvent(str, false);
44 bool EditorClient::shouldDeleteRange(Range*)
50 bool EditorClient::shouldShowDeleteInterface(HTMLElement*)
55 bool EditorClient::isContinuousSpellCheckingEnabled()
61 bool EditorClient::isGrammarCheckingEnabled()
67 int EditorClient::spellCheckerDocumentTag()
73 bool EditorClient::shouldBeginEditing(WebCore::Range*)
79 bool EditorClient::shouldEndEditing(WebCore::Range*)
85 bool EditorClient::shouldInsertText(String, Range*, EditorInsertAction)
91 bool EditorClient::shouldChangeSelectedRange(Range*, Range*, EAffinity, bool)
97 bool EditorClient::shouldApplyStyle(WebCore::CSSStyleDeclaration*,
104 bool EditorClient::shouldMoveRangeAfterDelete(WebCore::Range*, WebCore::Range*)
110 void EditorClient::didBeginEditing()
115 void EditorClient::respondToChangedContents()
120 void EditorClient::respondToChangedSelection()
125 void EditorClient::didEndEditing()
130 void EditorClient::didWriteSelectionToPasteboard()
135 void EditorClient::didSetSelectionTypesForPasteboard()
140 bool EditorClient::isEditable()
142 return webkit_web_view_get_editable(m_webView);
145 void EditorClient::registerCommandForUndo(WTF::PassRefPtr<WebCore::EditCommand>)
150 void EditorClient::registerCommandForRedo(WTF::PassRefPtr<WebCore::EditCommand>)
155 void EditorClient::clearUndoRedoOperations()
160 bool EditorClient::canUndo() const
166 bool EditorClient::canRedo() const
172 void EditorClient::undo()
177 void EditorClient::redo()
182 bool EditorClient::shouldInsertNode(Node*, Range*, EditorInsertAction)
188 void EditorClient::pageDestroyed()
193 bool EditorClient::smartInsertDeleteEnabled()
199 void EditorClient::toggleContinuousSpellChecking()
204 void EditorClient::toggleGrammarChecking()
208 void EditorClient::handleKeyboardEvent(KeyboardEvent* event)
210 Frame* frame = core(m_webView)->focusController()->focusedOrMainFrame();
211 if (!frame || !frame->document()->focusedNode())
214 const PlatformKeyboardEvent* kevent = event->keyEvent();
215 if (!kevent || kevent->type() == PlatformKeyboardEvent::KeyUp)
218 Node* start = frame->selectionController()->start().node();
222 // FIXME: Use GtkBindingSet instead of this hard-coded switch
223 // http://bugs.webkit.org/show_bug.cgi?id=15911
225 if (start->isContentEditable()) {
226 switch (kevent->windowsVirtualKeyCode()) {
228 frame->editor()->deleteWithDirection(SelectionController::BACKWARD,
229 kevent->ctrlKey() ? WordGranularity : CharacterGranularity, false, true);
232 frame->editor()->deleteWithDirection(SelectionController::FORWARD,
233 kevent->ctrlKey() ? WordGranularity : CharacterGranularity, false, true);
236 frame->selectionController()->modify(kevent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE,
237 SelectionController::LEFT,
238 kevent->ctrlKey() ? WordGranularity : CharacterGranularity,
242 frame->selectionController()->modify(kevent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE,
243 SelectionController::RIGHT,
244 kevent->ctrlKey() ? WordGranularity : CharacterGranularity,
248 frame->selectionController()->modify(kevent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE,
249 SelectionController::BACKWARD,
250 kevent->ctrlKey() ? ParagraphGranularity : LineGranularity,
254 frame->selectionController()->modify(kevent->shiftKey() ? SelectionController::EXTEND : SelectionController::MOVE,
255 SelectionController::FORWARD,
256 kevent->ctrlKey() ? ParagraphGranularity : LineGranularity,
259 case VK_PRIOR: // PageUp
260 frame->editor()->command("MovePageUp").execute();
262 case VK_NEXT: // PageDown
263 frame->editor()->command("MovePageDown").execute();
266 if (kevent->ctrlKey() && kevent->shiftKey())
267 frame->editor()->command("MoveToBeginningOfDocumentAndModifySelection").execute();
268 else if (kevent->ctrlKey())
269 frame->editor()->command("MoveToBeginningOfDocument").execute();
270 else if (kevent->shiftKey())
271 frame->editor()->command("MoveToBeginningOfLineAndModifySelection").execute();
273 frame->editor()->command("MoveToBeginningOfLine").execute();
276 if (kevent->ctrlKey() && kevent->shiftKey())
277 frame->editor()->command("MoveToEndOfDocumentAndModifySelection").execute();
278 else if (kevent->ctrlKey())
279 frame->editor()->command("MoveToEndOfDocument").execute();
280 else if (kevent->shiftKey())
281 frame->editor()->command("MoveToEndOfLineAndModifySelection").execute();
283 frame->editor()->command("MoveToEndOfLine").execute();
286 frame->editor()->command("InsertLineBreak").execute();
291 if (!kevent->ctrlKey() && !kevent->altKey() && !kevent->text().isEmpty()) {
292 if (kevent->text().length() == 1) {
293 UChar ch = kevent->text()[0];
294 // Don't insert null or control characters as they can result in unexpected behaviour
298 frame->editor()->insertText(kevent->text(), event);
299 } else if (kevent->ctrlKey()) {
300 switch (kevent->windowsVirtualKeyCode()) {
302 frame->editor()->command("ToggleBold").execute();
305 frame->editor()->command("ToggleItalic").execute();
308 frame->editor()->command("Redo").execute();
311 frame->editor()->command("Undo").execute();
319 switch (kevent->windowsVirtualKeyCode()) {
321 frame->editor()->command("MoveUp").execute();
324 frame->editor()->command("MoveDown").execute();
326 case VK_PRIOR: // PageUp
327 frame->editor()->command("MovePageUp").execute();
329 case VK_NEXT: // PageDown
330 frame->editor()->command("MovePageDown").execute();
333 if (kevent->ctrlKey())
334 frame->editor()->command("MoveToBeginningOfDocument").execute();
337 if (kevent->ctrlKey())
338 frame->editor()->command("MoveToEndOfDocument").execute();
344 event->setDefaultHandled();
348 void EditorClient::handleInputMethodKeydown(KeyboardEvent*)
353 EditorClient::EditorClient(WebKitWebView* webView)
356 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(m_webView);
357 g_signal_connect(webViewData->imContext, "commit", G_CALLBACK(imContextCommitted), this);
360 EditorClient::~EditorClient()
362 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(m_webView);
363 g_signal_handlers_disconnect_by_func(webViewData->imContext, (gpointer)imContextCommitted, this);
366 void EditorClient::textFieldDidBeginEditing(Element*)
368 gtk_im_context_focus_in(WEBKIT_WEB_VIEW_GET_PRIVATE(m_webView)->imContext);
371 void EditorClient::textFieldDidEndEditing(Element*)
373 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(m_webView);
375 gtk_im_context_focus_out(webViewData->imContext);
377 hildon_gtk_im_context_hide(webViewData->imContext);
381 void EditorClient::textDidChangeInTextField(Element*)
386 bool EditorClient::doTextFieldCommandFromEvent(Element*, KeyboardEvent*)
392 void EditorClient::textWillBeDeletedInTextField(Element*)
397 void EditorClient::textDidChangeInTextArea(Element*)
402 void EditorClient::ignoreWordInSpellDocument(const String&)
407 void EditorClient::learnWord(const String&)
412 void EditorClient::checkSpellingOfString(const UChar*, int, int*, int*)
417 void EditorClient::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
422 void EditorClient::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&)
427 void EditorClient::updateSpellingUIWithMisspelledWord(const String&)
432 void EditorClient::showSpellingUI(bool)
437 bool EditorClient::spellingUIIsShowing()
443 void EditorClient::getGuessesForWord(const String&, Vector<String>&)
448 void EditorClient::setInputMethodState(bool)