WebKit/wx/WebKitSupport/EditorClientWx.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com>
       
     3  *
       
     4  * All rights reserved.
       
     5  *
       
     6  * Redistribution and use in source and binary forms, with or without
       
     7  * modification, are permitted provided that the following conditions
       
     8  * are met:
       
     9  * 1. Redistributions of source code must retain the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer.
       
    11  * 2. Redistributions in binary form must reproduce the above copyright
       
    12  *    notice, this list of conditions and the following disclaimer in the
       
    13  *    documentation and/or other materials provided with the distribution.
       
    14  *
       
    15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
       
    16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
       
    19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
       
    23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    26  */
       
    27 #include "config.h"
       
    28 #include "EditorClientWx.h"
       
    29 
       
    30 #include "EditCommand.h"
       
    31 #include "Editor.h"
       
    32 #include "FocusController.h"
       
    33 #include "Frame.h"
       
    34 #include "FrameView.h"
       
    35 #include "HostWindow.h"
       
    36 #include "KeyboardEvent.h"
       
    37 #include "NotImplemented.h"
       
    38 #include "Page.h"
       
    39 #include "PlatformKeyboardEvent.h"
       
    40 #include "PlatformString.h"
       
    41 #include "SelectionController.h"
       
    42 #include "WebFrame.h"
       
    43 #include "WebFramePrivate.h"
       
    44 #include "WebView.h"
       
    45 #include "WebViewPrivate.h"
       
    46 #include "WindowsKeyboardCodes.h"
       
    47 
       
    48 #include <stdio.h>
       
    49 
       
    50 namespace WebCore {
       
    51 
       
    52 static const unsigned CtrlKey = 1 << 0;
       
    53 static const unsigned AltKey = 1 << 1;
       
    54 static const unsigned ShiftKey = 1 << 2;
       
    55 
       
    56 struct KeyDownEntry {
       
    57     unsigned virtualKey;
       
    58     unsigned modifiers;
       
    59     const char* name;
       
    60 };
       
    61 
       
    62 struct KeyPressEntry {
       
    63     unsigned charCode;
       
    64     unsigned modifiers;
       
    65     const char* name;
       
    66 };
       
    67 
       
    68 static const KeyDownEntry keyDownEntries[] = {
       
    69     { VK_LEFT,   0,                  "MoveLeft"                                    },
       
    70     { VK_LEFT,   ShiftKey,           "MoveLeftAndModifySelection"                  },
       
    71     { VK_LEFT,   CtrlKey,            "MoveWordLeft"                                },
       
    72     { VK_LEFT,   CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection"              },
       
    73     { VK_RIGHT,  0,                  "MoveRight"                                   },
       
    74     { VK_RIGHT,  ShiftKey,           "MoveRightAndModifySelection"                 },
       
    75     { VK_RIGHT,  CtrlKey,            "MoveWordRight"                               },
       
    76     { VK_RIGHT,  CtrlKey | ShiftKey, "MoveWordRightAndModifySelection"             },
       
    77     { VK_UP,     0,                  "MoveUp"                                      },
       
    78     { VK_UP,     ShiftKey,           "MoveUpAndModifySelection"                    },
       
    79     { VK_PRIOR,  ShiftKey,           "MovePageUpAndModifySelection"                },
       
    80     { VK_DOWN,   0,                  "MoveDown"                                    },
       
    81     { VK_DOWN,   ShiftKey,           "MoveDownAndModifySelection"                  },
       
    82     { VK_NEXT,   ShiftKey,           "MovePageDownAndModifySelection"              },
       
    83     { VK_PRIOR,  0,                  "MovePageUp"                                  },
       
    84     { VK_NEXT,   0,                  "MovePageDown"                                },
       
    85     { VK_HOME,   0,                  "MoveToBeginningOfLine"                       },
       
    86     { VK_HOME,   ShiftKey,           "MoveToBeginningOfLineAndModifySelection"     },
       
    87     { VK_HOME,   CtrlKey,            "MoveToBeginningOfDocument"                   },
       
    88     { VK_HOME,   CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" },
       
    89 
       
    90     { VK_END,    0,                  "MoveToEndOfLine"                             },
       
    91     { VK_END,    ShiftKey,           "MoveToEndOfLineAndModifySelection"           },
       
    92     { VK_END,    CtrlKey,            "MoveToEndOfDocument"                         },
       
    93     { VK_END,    CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection"       },
       
    94 
       
    95     { VK_BACK,   0,                  "DeleteBackward"                              },
       
    96     { VK_BACK,   ShiftKey,           "DeleteBackward"                              },
       
    97     { VK_DELETE, 0,                  "DeleteForward"                               },
       
    98     { VK_BACK,   CtrlKey,            "DeleteWordBackward"                          },
       
    99     { VK_DELETE, CtrlKey,            "DeleteWordForward"                           },
       
   100     
       
   101     { 'B',       CtrlKey,            "ToggleBold"                                  },
       
   102     { 'I',       CtrlKey,            "ToggleItalic"                                },
       
   103 
       
   104     { VK_ESCAPE, 0,                  "Cancel"                                      },
       
   105     //FIXME: this'll never happen. We can trash it or make it a normal period
       
   106     { VK_OEM_PERIOD, CtrlKey,        "Cancel"                                      },
       
   107     { VK_TAB,    0,                  "InsertTab"                                   },
       
   108     { VK_TAB,    ShiftKey,           "InsertBacktab"                               },
       
   109     { VK_RETURN, 0,                  "InsertNewline"                               },
       
   110     { VK_RETURN, CtrlKey,            "InsertNewline"                               },
       
   111     { VK_RETURN, AltKey,             "InsertNewline"                               },
       
   112     { VK_RETURN, AltKey | ShiftKey,  "InsertNewline"                               },
       
   113     { 'A',       CtrlKey,            "SelectAll"                                   },
       
   114     { 'Z',       CtrlKey,            "Undo"                                        },
       
   115     { 'Z',       CtrlKey | ShiftKey, "Redo"                                        },
       
   116 };
       
   117 
       
   118 static const KeyPressEntry keyPressEntries[] = {
       
   119     { '\t',   0,                  "InsertTab"                                   },
       
   120     { '\t',   ShiftKey,           "InsertBacktab"                               },
       
   121     { '\r',   0,                  "InsertNewline"                               },
       
   122     { '\r',   CtrlKey,            "InsertNewline"                               },
       
   123     { '\r',   AltKey,             "InsertNewline"                               },
       
   124     { '\r',   AltKey | ShiftKey,  "InsertNewline"                               },
       
   125 };
       
   126 
       
   127 EditorClientWx::~EditorClientWx()
       
   128 {
       
   129     m_page = NULL;
       
   130 }
       
   131 
       
   132 void EditorClientWx::setPage(Page* page)
       
   133 {
       
   134     m_page = page;
       
   135 }
       
   136 
       
   137 void EditorClientWx::pageDestroyed()
       
   138 {
       
   139     delete this;
       
   140 }
       
   141 
       
   142 bool EditorClientWx::shouldDeleteRange(Range*)
       
   143 {
       
   144     notImplemented();
       
   145     return true;
       
   146 }
       
   147 
       
   148 bool EditorClientWx::shouldShowDeleteInterface(HTMLElement*)
       
   149 {
       
   150     notImplemented();
       
   151     return false;
       
   152 }
       
   153 
       
   154 bool EditorClientWx::smartInsertDeleteEnabled()
       
   155 {
       
   156     notImplemented();
       
   157     return false;
       
   158 }
       
   159 
       
   160 bool EditorClientWx::isSelectTrailingWhitespaceEnabled()
       
   161 {
       
   162     notImplemented();
       
   163     return false;
       
   164 }
       
   165 
       
   166 bool EditorClientWx::isContinuousSpellCheckingEnabled()
       
   167 {
       
   168     notImplemented();
       
   169     return false;
       
   170 }
       
   171 
       
   172 void EditorClientWx::toggleContinuousSpellChecking()
       
   173 {
       
   174     notImplemented();
       
   175 }
       
   176 
       
   177 bool EditorClientWx::isGrammarCheckingEnabled()
       
   178 {
       
   179     notImplemented();
       
   180     return false;
       
   181 }
       
   182 
       
   183 void EditorClientWx::toggleGrammarChecking()
       
   184 {
       
   185     notImplemented();
       
   186 }
       
   187 
       
   188 int EditorClientWx::spellCheckerDocumentTag()
       
   189 {
       
   190     notImplemented();
       
   191     return 0;
       
   192 }
       
   193 
       
   194 bool EditorClientWx::selectWordBeforeMenuEvent()
       
   195 {
       
   196     notImplemented();
       
   197     return false;
       
   198 }
       
   199 
       
   200 bool EditorClientWx::isEditable()
       
   201 {
       
   202     Frame* frame = m_page->focusController()->focusedOrMainFrame();
       
   203 
       
   204     if (frame) {
       
   205         wxWebView* webKitWin = dynamic_cast<wxWebView*>(frame->view()->hostWindow()->platformPageClient());
       
   206         if (webKitWin) 
       
   207             return webKitWin->IsEditable();
       
   208     }
       
   209     return false;
       
   210 }
       
   211 
       
   212 bool EditorClientWx::shouldBeginEditing(Range*)
       
   213 {
       
   214     notImplemented();
       
   215     return true;
       
   216 }
       
   217 
       
   218 bool EditorClientWx::shouldEndEditing(Range*)
       
   219 {
       
   220     notImplemented();
       
   221     return true;
       
   222 }
       
   223 
       
   224 bool EditorClientWx::shouldInsertNode(Node*, Range*,
       
   225                                        EditorInsertAction)
       
   226 {
       
   227     notImplemented();
       
   228     return true;
       
   229 }
       
   230 
       
   231 bool EditorClientWx::shouldInsertText(const String&, Range*,
       
   232                                        EditorInsertAction)
       
   233 {
       
   234     notImplemented();
       
   235     return true;
       
   236 }
       
   237 
       
   238 bool EditorClientWx::shouldApplyStyle(CSSStyleDeclaration*,
       
   239                                        Range*)
       
   240 {
       
   241     notImplemented();
       
   242     return true;
       
   243 }
       
   244 
       
   245 bool EditorClientWx::shouldMoveRangeAfterDelete(Range*, Range*)
       
   246 {
       
   247     notImplemented();
       
   248     return true;
       
   249 }
       
   250 
       
   251 bool EditorClientWx::shouldChangeSelectedRange(Range* fromRange, Range* toRange, 
       
   252                                 EAffinity, bool stillSelecting)
       
   253 {
       
   254     notImplemented();
       
   255     return true;
       
   256 }
       
   257 
       
   258 void EditorClientWx::didBeginEditing()
       
   259 {
       
   260     notImplemented();
       
   261 }
       
   262 
       
   263 void EditorClientWx::respondToChangedContents()
       
   264 {
       
   265     notImplemented();
       
   266 }
       
   267 
       
   268 void EditorClientWx::didEndEditing()
       
   269 {
       
   270     notImplemented();
       
   271 }
       
   272 
       
   273 void EditorClientWx::didWriteSelectionToPasteboard()
       
   274 {
       
   275     notImplemented();
       
   276 }
       
   277 
       
   278 void EditorClientWx::didSetSelectionTypesForPasteboard()
       
   279 {
       
   280     notImplemented();
       
   281 }
       
   282 
       
   283 void EditorClientWx::registerCommandForUndo(PassRefPtr<EditCommand> command)
       
   284 {
       
   285     Frame* frame = m_page->focusController()->focusedOrMainFrame();
       
   286 
       
   287     if (frame) {
       
   288         wxWebView* webKitWin = dynamic_cast<wxWebView*>(frame->view()->hostWindow()->platformPageClient());
       
   289         if (webKitWin) {
       
   290             webKitWin->m_impl->undoStack.append(EditCommandWx(command));
       
   291         }
       
   292     }
       
   293 }
       
   294 
       
   295 void EditorClientWx::registerCommandForRedo(PassRefPtr<EditCommand> command)
       
   296 {
       
   297     Frame* frame = m_page->focusController()->focusedOrMainFrame();
       
   298 
       
   299     if (frame) {
       
   300         wxWebView* webKitWin = dynamic_cast<wxWebView*>(frame->view()->hostWindow()->platformPageClient());
       
   301         if (webKitWin) {
       
   302             webKitWin->m_impl->redoStack.insert(0, EditCommandWx(command));
       
   303         }
       
   304     }
       
   305 }
       
   306 
       
   307 void EditorClientWx::clearUndoRedoOperations()
       
   308 {
       
   309     Frame* frame = m_page->focusController()->focusedOrMainFrame();
       
   310     
       
   311     if (frame) {
       
   312         wxWebView* webKitWin = dynamic_cast<wxWebView*>(frame->view()->hostWindow()->platformPageClient());
       
   313         if (webKitWin) {
       
   314             webKitWin->m_impl->redoStack.clear();
       
   315             webKitWin->m_impl->undoStack.clear();
       
   316         }
       
   317     }
       
   318 }
       
   319 
       
   320 bool EditorClientWx::canUndo() const
       
   321 {
       
   322     Frame* frame = m_page->focusController()->focusedOrMainFrame();
       
   323 
       
   324     if (frame) {
       
   325         wxWebView* webKitWin = dynamic_cast<wxWebView*>(frame->view()->hostWindow()->platformPageClient());
       
   326         if (webKitWin) {
       
   327             return webKitWin->m_impl->undoStack.size() != 0;
       
   328         }
       
   329     }
       
   330     return false;
       
   331 }
       
   332 
       
   333 bool EditorClientWx::canRedo() const
       
   334 {
       
   335     Frame* frame = m_page->focusController()->focusedOrMainFrame();
       
   336 
       
   337     if (frame) {
       
   338         wxWebView* webKitWin = dynamic_cast<wxWebView*>(frame->view()->hostWindow()->platformPageClient());
       
   339         if (webKitWin && webKitWin) {
       
   340             return webKitWin->m_impl->redoStack.size() != 0;
       
   341         }
       
   342     }
       
   343     return false;
       
   344 }
       
   345 
       
   346 void EditorClientWx::undo()
       
   347 {
       
   348     Frame* frame = m_page->focusController()->focusedOrMainFrame();
       
   349 
       
   350     if (frame) {
       
   351         wxWebView* webKitWin = dynamic_cast<wxWebView*>(frame->view()->hostWindow()->platformPageClient());
       
   352         if (webKitWin) {
       
   353             webKitWin->m_impl->undoStack.last().editCommand()->unapply();
       
   354             webKitWin->m_impl->undoStack.removeLast();
       
   355         }
       
   356     }
       
   357 }
       
   358 
       
   359 void EditorClientWx::redo()
       
   360 {
       
   361     Frame* frame = m_page->focusController()->focusedOrMainFrame();
       
   362 
       
   363     if (frame) {    
       
   364         wxWebView* webKitWin = dynamic_cast<wxWebView*>(frame->view()->hostWindow()->platformPageClient());
       
   365         if (webKitWin) {
       
   366             webKitWin->m_impl->redoStack.first().editCommand()->reapply();
       
   367             webKitWin->m_impl->redoStack.remove(0);
       
   368         }
       
   369     }
       
   370 }
       
   371 
       
   372 bool EditorClientWx::handleEditingKeyboardEvent(KeyboardEvent* event)
       
   373 {
       
   374     Node* node = event->target()->toNode();
       
   375     ASSERT(node);
       
   376     Frame* frame = node->document()->frame();
       
   377     ASSERT(frame);
       
   378 
       
   379     const PlatformKeyboardEvent* keyEvent = event->keyEvent();
       
   380 
       
   381     //NB: this is what windows does, but they also have a keypress event for Alt+Enter which clearly won't get hit with this
       
   382     if (!keyEvent || keyEvent->altKey())  // do not treat this as text input if Alt is down
       
   383         return false;
       
   384 
       
   385     Editor::Command command = frame->editor()->command(interpretKeyEvent(event));
       
   386 
       
   387     if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
       
   388         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
       
   389         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or if not to let a CHAR event be generated
       
   390         // (e.g. Tab that inserts a Tab character, or Enter).
       
   391         return !command.isTextInsertion() && command.execute(event);
       
   392     }
       
   393 
       
   394      if (command.execute(event))
       
   395         return true;
       
   396 
       
   397     // Don't insert null or control characters as they can result in unexpected behaviour
       
   398     if (event->charCode() < ' ')
       
   399         return false;
       
   400 
       
   401     return frame->editor()->insertText(event->keyEvent()->text(), event);
       
   402 }
       
   403 
       
   404 const char* EditorClientWx::interpretKeyEvent(const KeyboardEvent* evt)
       
   405 {
       
   406     ASSERT(evt->keyEvent()->type() == PlatformKeyboardEvent::RawKeyDown || evt->keyEvent()->type() == PlatformKeyboardEvent::Char);
       
   407 
       
   408     static HashMap<int, const char*>* keyDownCommandsMap = 0;
       
   409     static HashMap<int, const char*>* keyPressCommandsMap = 0;
       
   410 
       
   411     if (!keyDownCommandsMap) {
       
   412         keyDownCommandsMap = new HashMap<int, const char*>;
       
   413         keyPressCommandsMap = new HashMap<int, const char*>;
       
   414 
       
   415         for (unsigned i = 0; i < WXSIZEOF(keyDownEntries); i++)
       
   416             keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
       
   417 
       
   418         for (unsigned i = 0; i < WXSIZEOF(keyPressEntries); i++)
       
   419             keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
       
   420     }
       
   421 
       
   422     unsigned modifiers = 0;
       
   423     if (evt->shiftKey())
       
   424         modifiers |= ShiftKey;
       
   425     if (evt->altKey())
       
   426         modifiers |= AltKey;
       
   427     if (evt->ctrlKey())
       
   428         modifiers |= CtrlKey;
       
   429 
       
   430     if (evt->keyEvent()->type() == PlatformKeyboardEvent::RawKeyDown) {
       
   431         int mapKey = modifiers << 16 | evt->keyCode();
       
   432         return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
       
   433     }
       
   434 
       
   435     int mapKey = modifiers << 16 | evt->charCode();
       
   436     return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
       
   437 }
       
   438 
       
   439 
       
   440 void EditorClientWx::handleInputMethodKeydown(KeyboardEvent* event)
       
   441 {
       
   442 // NOTE: we don't currently need to handle this. When key events occur,
       
   443 // both this method and handleKeyboardEvent get a chance at handling them.
       
   444 // We might use this method later on for IME-specific handling.
       
   445 }
       
   446 
       
   447 void EditorClientWx::handleKeyboardEvent(KeyboardEvent* event)
       
   448 {
       
   449     if (handleEditingKeyboardEvent(event))
       
   450         event->setDefaultHandled();
       
   451 }
       
   452 
       
   453 void EditorClientWx::textFieldDidBeginEditing(Element*)
       
   454 {
       
   455     notImplemented();
       
   456 }
       
   457 
       
   458 void EditorClientWx::textFieldDidEndEditing(Element*)
       
   459 {
       
   460     notImplemented();
       
   461 }
       
   462 
       
   463 void EditorClientWx::textDidChangeInTextField(Element*)
       
   464 {
       
   465     notImplemented();
       
   466 }
       
   467 
       
   468 bool EditorClientWx::doTextFieldCommandFromEvent(Element*, KeyboardEvent*)
       
   469 {
       
   470     notImplemented();
       
   471     return false;
       
   472 }
       
   473 
       
   474 void EditorClientWx::textWillBeDeletedInTextField(Element*)
       
   475 {
       
   476     notImplemented();
       
   477 }
       
   478 
       
   479 void EditorClientWx::textDidChangeInTextArea(Element*)
       
   480 {
       
   481     notImplemented();
       
   482 }
       
   483 
       
   484 void EditorClientWx::respondToChangedSelection()
       
   485 {
       
   486     notImplemented();
       
   487 }
       
   488 
       
   489 void EditorClientWx::ignoreWordInSpellDocument(const String&) 
       
   490 { 
       
   491     notImplemented(); 
       
   492 }
       
   493 
       
   494 void EditorClientWx::learnWord(const String&) 
       
   495 { 
       
   496     notImplemented(); 
       
   497 }
       
   498 
       
   499 void EditorClientWx::checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) 
       
   500 { 
       
   501     notImplemented(); 
       
   502 }
       
   503 
       
   504 void EditorClientWx::checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) 
       
   505 { 
       
   506     notImplemented(); 
       
   507 }
       
   508 
       
   509 void EditorClientWx::updateSpellingUIWithGrammarString(const String&, const GrammarDetail& detail) 
       
   510 { 
       
   511     notImplemented(); 
       
   512 }
       
   513 
       
   514 void EditorClientWx::updateSpellingUIWithMisspelledWord(const String&) 
       
   515 { 
       
   516     notImplemented(); 
       
   517 }
       
   518 
       
   519 void EditorClientWx::showSpellingUI(bool show) 
       
   520 { 
       
   521     notImplemented(); 
       
   522 }
       
   523 
       
   524 bool EditorClientWx::spellingUIIsShowing() 
       
   525 { 
       
   526     notImplemented(); 
       
   527     return false;
       
   528 }
       
   529 
       
   530 void EditorClientWx::getGuessesForWord(const String&, Vector<String>& guesses) 
       
   531 { 
       
   532     notImplemented(); 
       
   533 }
       
   534 
       
   535 String EditorClientWx::getAutoCorrectSuggestionForMisspelledWord(const WebCore::String&)
       
   536 {
       
   537     notImplemented();
       
   538     return String();
       
   539 }
       
   540 
       
   541 void EditorClientWx::willSetInputMethodState()
       
   542 {
       
   543     notImplemented();
       
   544 }
       
   545 
       
   546 void EditorClientWx::setInputMethodState(bool enabled)
       
   547 {
       
   548     notImplemented();
       
   549 }
       
   550 
       
   551 }