1/*
2 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2006 Zack Rusin <zack@kde.org>
4 * Copyright (C) 2006 Apple Computer, Inc.
5 * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
6 * Copyright (C) 2007 Andrea Anzani <andrea.anzani@gmail.com>
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "config.h"
33#include "EditorClientHaiku.h"
34
35#include "Document.h"
36#include "Editor.h"
37#include "FocusController.h"
38#include "Frame.h"
39#include "KeyboardEvent.h"
40#include "NotImplemented.h"
41#include "Page.h"
42#include "PlatformKeyboardEvent.h"
43#include "WindowsKeyboardCodes.h"
44
45
46namespace WebCore {
47
48EditorClientHaiku::EditorClientHaiku()
49    : m_editing(false)
50    , m_inUndoRedo(false)
51{
52}
53
54void EditorClientHaiku::setPage(Page* page)
55{
56    m_page = page;
57}
58
59void EditorClientHaiku::pageDestroyed()
60{
61    notImplemented();
62}
63
64bool EditorClientHaiku::shouldDeleteRange(Range*)
65{
66    notImplemented();
67    return true;
68}
69
70bool EditorClientHaiku::shouldShowDeleteInterface(HTMLElement*)
71{
72    notImplemented();
73    return false;
74}
75
76bool EditorClientHaiku::smartInsertDeleteEnabled()
77{
78    notImplemented();
79    return false;
80}
81
82bool EditorClientHaiku::isSelectTrailingWhitespaceEnabled()
83{
84    notImplemented();
85    return false;
86}
87
88bool EditorClientHaiku::isContinuousSpellCheckingEnabled()
89{
90    notImplemented();
91    return false;
92}
93
94void EditorClientHaiku::toggleContinuousSpellChecking()
95{
96    notImplemented();
97}
98
99bool EditorClientHaiku::isGrammarCheckingEnabled()
100{
101    notImplemented();
102    return false;
103}
104
105void EditorClientHaiku::toggleGrammarChecking()
106{
107    notImplemented();
108}
109
110int EditorClientHaiku::spellCheckerDocumentTag()
111{
112    notImplemented();
113    return 0;
114}
115
116bool EditorClientHaiku::shouldBeginEditing(WebCore::Range*)
117{
118    notImplemented();
119    return true;
120}
121
122bool EditorClientHaiku::shouldEndEditing(WebCore::Range*)
123{
124    notImplemented();
125    return true;
126}
127
128bool EditorClientHaiku::shouldInsertNode(Node*, Range*, EditorInsertAction)
129{
130    notImplemented();
131    return true;
132}
133
134bool EditorClientHaiku::shouldInsertText(const String&, Range*, EditorInsertAction)
135{
136    notImplemented();
137    return true;
138}
139
140bool EditorClientHaiku::shouldChangeSelectedRange(Range* fromRange, Range* toRange,
141                                                  EAffinity, bool stillSelecting)
142{
143    notImplemented();
144    return true;
145}
146
147bool EditorClientHaiku::shouldApplyStyle(WebCore::CSSStyleDeclaration*,
148                                      WebCore::Range*)
149{
150    notImplemented();
151    return true;
152}
153
154bool EditorClientHaiku::shouldMoveRangeAfterDelete(Range*, Range*)
155{
156    notImplemented();
157    return true;
158}
159
160void EditorClientHaiku::didBeginEditing()
161{
162    notImplemented();
163    m_editing = true;
164}
165
166void EditorClientHaiku::respondToChangedContents()
167{
168    notImplemented();
169}
170
171void EditorClientHaiku::respondToChangedSelection()
172{
173    notImplemented();
174}
175
176void EditorClientHaiku::didEndEditing()
177{
178    notImplemented();
179    m_editing = false;
180}
181
182void EditorClientHaiku::didWriteSelectionToPasteboard()
183{
184    notImplemented();
185}
186
187void EditorClientHaiku::didSetSelectionTypesForPasteboard()
188{
189    notImplemented();
190}
191
192void EditorClientHaiku::registerCommandForUndo(WTF::PassRefPtr<WebCore::EditCommand> cmd)
193{
194    notImplemented();
195}
196
197void EditorClientHaiku::registerCommandForRedo(WTF::PassRefPtr<WebCore::EditCommand>)
198{
199    notImplemented();
200}
201
202void EditorClientHaiku::clearUndoRedoOperations()
203{
204    notImplemented();
205}
206
207bool EditorClientHaiku::canCopyCut(bool defaultValue) const
208{
209    return defaultValue;
210}
211
212bool EditorClientHaiku::canPaste(bool defaultValue) const
213{
214    return defaultValue;
215}
216
217bool EditorClientHaiku::canUndo() const
218{
219    notImplemented();
220    return false;
221}
222
223bool EditorClientHaiku::canRedo() const
224{
225    notImplemented();
226    return false;
227}
228
229void EditorClientHaiku::undo()
230{
231    notImplemented();
232    m_inUndoRedo = true;
233    m_inUndoRedo = false;
234}
235
236void EditorClientHaiku::redo()
237{
238    notImplemented();
239    m_inUndoRedo = true;
240    m_inUndoRedo = false;
241}
242
243void EditorClientHaiku::handleKeyboardEvent(KeyboardEvent* event)
244{
245    Frame* frame = m_page->focusController()->focusedOrMainFrame();
246    if (!frame || !frame->document()->focusedNode())
247        return;
248
249    const PlatformKeyboardEvent* kevent = event->keyEvent();
250    if (!kevent || kevent->type() == PlatformKeyboardEvent::KeyUp)
251        return;
252
253    Node* start = frame->selection()->start().containerNode();
254    if (!start)
255        return;
256
257    if (start->isContentEditable()) {
258        switch (kevent->windowsVirtualKeyCode()) {
259        case VK_BACK:
260            frame->editor()->deleteWithDirection(DirectionBackward,
261                                                 kevent->ctrlKey() ? WordGranularity : CharacterGranularity,
262                                                 false, true);
263            break;
264        case VK_DELETE:
265            frame->editor()->deleteWithDirection(DirectionForward,
266                                                 kevent->ctrlKey() ? WordGranularity : CharacterGranularity,
267                                                 false, true);
268            break;
269        case VK_LEFT:
270            frame->selection()->modify(kevent->shiftKey() ? SelectionController::AlterationExtend : SelectionController::AlterationMove,
271                                       DirectionLeft,
272                                       kevent->ctrlKey() ? WordGranularity : CharacterGranularity,
273                                       true);
274            break;
275        case VK_RIGHT:
276            frame->selection()->modify(kevent->shiftKey() ? SelectionController::AlterationExtend : SelectionController::AlterationMove,
277                                       DirectionRight,
278                                       kevent->ctrlKey() ? WordGranularity : CharacterGranularity,
279                                       true);
280            break;
281        case VK_UP:
282            frame->selection()->modify(kevent->shiftKey() ? SelectionController::AlterationExtend : SelectionController::AlterationMove,
283                                       DirectionBackward,
284                                       kevent->ctrlKey() ? ParagraphGranularity : LineGranularity,
285                                       true);
286            break;
287        case VK_DOWN:
288            frame->selection()->modify(kevent->shiftKey() ? SelectionController::AlterationExtend : SelectionController::AlterationMove,
289                                       DirectionForward,
290                                       kevent->ctrlKey() ? ParagraphGranularity : LineGranularity,
291                                       true);
292            break;
293        case VK_PRIOR: // PageUp
294            frame->editor()->command("MoveUpByPageAndModifyCaret");
295            break;
296        case VK_NEXT: // PageDown
297            frame->editor()->command("MoveDownByPageAndModifyCaret");
298            break;
299        case VK_RETURN:
300            frame->editor()->command("InsertLineBreak");
301            break;
302        case VK_TAB:
303            return;
304        default:
305            if (!kevent->ctrlKey() && !kevent->altKey() && !kevent->text().isEmpty()) {
306                if (kevent->text().length() == 1) {
307                    UChar ch = kevent->text()[0];
308                    // Don't insert null or control characters as they can result in unexpected behaviour
309                    if (ch < ' ')
310                        break;
311                }
312                frame->editor()->insertText(kevent->text(), event);
313            } else if (kevent->ctrlKey()) {
314                switch (kevent->windowsVirtualKeyCode()) {
315                case VK_A:
316                    frame->editor()->command("SelectAll");
317                    break;
318                case VK_B:
319                    frame->editor()->command("ToggleBold");
320                    break;
321                case VK_C:
322                    frame->editor()->command("Copy");
323                    break;
324                case VK_I:
325                    frame->editor()->command("ToggleItalic");
326                    break;
327                case VK_V:
328                    frame->editor()->command("Paste");
329                    break;
330                case VK_X:
331                    frame->editor()->command("Cut");
332                    break;
333                case VK_Y:
334                    frame->editor()->command("Redo");
335                    break;
336                case VK_Z:
337                    frame->editor()->command("Undo");
338                    break;
339                default:
340                    return;
341                }
342            } else
343                return;
344        }
345    } else {
346        switch (kevent->windowsVirtualKeyCode()) {
347        case VK_UP:
348            frame->editor()->command("MoveUp");
349            break;
350        case VK_DOWN:
351            frame->editor()->command("MoveDown");
352            break;
353        case VK_PRIOR: // PageUp
354            frame->editor()->command("MoveUpByPageAndModifyCaret");
355            break;
356        case VK_NEXT: // PageDown
357            frame->editor()->command("MoveDownByPageAndModifyCaret");
358            break;
359        case VK_HOME:
360            if (kevent->ctrlKey())
361                frame->editor()->command("MoveToBeginningOfDocument");
362            break;
363        case VK_END:
364            if (kevent->ctrlKey())
365                frame->editor()->command("MoveToEndOfDocument");
366            break;
367        default:
368            if (kevent->ctrlKey()) {
369                switch (kevent->windowsVirtualKeyCode()) {
370                case VK_A:
371                    frame->editor()->command("SelectAll");
372                    break;
373                case VK_C: case VK_X:
374                    frame->editor()->command("Copy");
375                    break;
376                default:
377                    return;
378                }
379            } else
380                return;
381        }
382    }
383    event->setDefaultHandled();
384}
385
386void EditorClientHaiku::handleInputMethodKeydown(KeyboardEvent*)
387{
388    notImplemented();
389}
390
391void EditorClientHaiku::textFieldDidBeginEditing(Element*)
392{
393    m_editing = true;
394}
395
396void EditorClientHaiku::textFieldDidEndEditing(Element*)
397{
398    m_editing = false;
399}
400
401void EditorClientHaiku::textDidChangeInTextField(Element*)
402{
403    notImplemented();
404}
405
406bool EditorClientHaiku::doTextFieldCommandFromEvent(Element*, KeyboardEvent*)
407{
408    return false;
409}
410
411void EditorClientHaiku::textWillBeDeletedInTextField(Element*)
412{
413    notImplemented();
414}
415
416void EditorClientHaiku::textDidChangeInTextArea(Element*)
417{
418    notImplemented();
419}
420
421void EditorClientHaiku::ignoreWordInSpellDocument(const String&)
422{
423    notImplemented();
424}
425
426void EditorClientHaiku::learnWord(const String&)
427{
428    notImplemented();
429}
430
431void EditorClientHaiku::checkSpellingOfString(const UChar*, int, int*, int*)
432{
433    notImplemented();
434}
435
436String EditorClientHaiku::getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord)
437{
438    notImplemented();
439    return String();
440}
441
442void EditorClientHaiku::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
443{
444    notImplemented();
445}
446
447void EditorClientHaiku::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&)
448{
449    notImplemented();
450}
451
452void EditorClientHaiku::updateSpellingUIWithMisspelledWord(const String&)
453{
454    notImplemented();
455}
456
457void EditorClientHaiku::showSpellingUI(bool)
458{
459    notImplemented();
460}
461
462bool EditorClientHaiku::spellingUIIsShowing()
463{
464    notImplemented();
465    return false;
466}
467
468void EditorClientHaiku::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses)
469{
470    notImplemented();
471}
472
473void EditorClientHaiku::willSetInputMethodState()
474{
475    notImplemented();
476}
477
478void EditorClientHaiku::setInputMethodState(bool enabled)
479{
480    notImplemented();
481}
482
483bool EditorClientHaiku::isEditing() const
484{
485    return m_editing;
486}
487
488} // namespace WebCore
489