~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebKit/qt/WebCoreSupport/EditorClientQt.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
 
3
 * Copyright (C) 2006 Zack Rusin <zack@kde.org>
 
4
 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
 
5
 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
 
6
 *
 
7
 * All rights reserved.
 
8
 *
 
9
 * Redistribution and use in source and binary forms, with or without
 
10
 * modification, are permitted provided that the following conditions
 
11
 * are met:
 
12
 * 1. Redistributions of source code must retain the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer.
 
14
 * 2. Redistributions in binary form must reproduce the above copyright
 
15
 *    notice, this list of conditions and the following disclaimer in the
 
16
 *    documentation and/or other materials provided with the distribution.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 
19
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
21
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 
22
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
23
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
24
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
25
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 
26
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
28
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
 */
 
30
 
 
31
#include "config.h"
 
32
#include "EditorClientQt.h"
 
33
 
 
34
#include "Document.h"
 
35
#include "UndoStepQt.h"
 
36
#include "Editor.h"
 
37
#include "FocusController.h"
 
38
#include "Frame.h"
 
39
#include "HTMLElement.h"
 
40
#include "HTMLInputElement.h"
 
41
#include "HTMLNames.h"
 
42
#include "KeyboardEvent.h"
 
43
#include "NotImplemented.h"
 
44
#include "Page.h"
 
45
#include "Pasteboard.h"
 
46
#include "PlatformKeyboardEvent.h"
 
47
#include "QWebPageClient.h"
 
48
#include "Range.h"
 
49
#include "Settings.h"
 
50
#include "SpatialNavigation.h"
 
51
#include "StylePropertySet.h"
 
52
#include "WindowsKeyboardCodes.h"
 
53
#include "qguiapplication.h"
 
54
#include "qwebpage.h"
 
55
#include "qwebpage_p.h"
 
56
 
 
57
#include <QClipboard>
 
58
#include <QUndoStack>
 
59
#include <stdio.h>
 
60
#include <wtf/OwnPtr.h>
 
61
 
 
62
 
 
63
static QString dumpPath(WebCore::Node *node)
 
64
{
 
65
    QString str = node->nodeName();
 
66
 
 
67
    WebCore::Node *parent = node->parentNode();
 
68
    while (parent) {
 
69
        str.append(QLatin1String(" > "));
 
70
        str.append(parent->nodeName());
 
71
        parent = parent->parentNode();
 
72
    }
 
73
    return str;
 
74
}
 
75
 
 
76
static QString dumpRange(WebCore::Range *range)
 
77
{
 
78
    if (!range)
 
79
        return QLatin1String("(null)");
 
80
    WebCore::ExceptionCode code;
 
81
 
 
82
    QString str = QString::fromLatin1("range from %1 of %2 to %3 of %4")
 
83
            .arg(range->startOffset(code)).arg(dumpPath(range->startContainer(code)))
 
84
            .arg(range->endOffset(code)).arg(dumpPath(range->endContainer(code)));
 
85
 
 
86
    return str;
 
87
}
 
88
 
 
89
 
 
90
namespace WebCore {
 
91
 
 
92
bool EditorClientQt::dumpEditingCallbacks = false;
 
93
bool EditorClientQt::acceptsEditing = true;
 
94
 
 
95
using namespace HTMLNames;
 
96
 
 
97
bool EditorClientQt::shouldDeleteRange(Range* range)
 
98
{
 
99
    if (dumpEditingCallbacks)
 
100
        printf("EDITING DELEGATE: shouldDeleteDOMRange:%s\n", dumpRange(range).toUtf8().constData());
 
101
 
 
102
    return true;
 
103
}
 
104
 
 
105
bool EditorClientQt::shouldShowDeleteInterface(HTMLElement* element)
 
106
{
 
107
    if (QWebPagePrivate::drtRun)
 
108
        return element->getAttribute(classAttr) == "needsDeletionUI";
 
109
    return false;
 
110
}
 
111
 
 
112
bool EditorClientQt::isContinuousSpellCheckingEnabled()
 
113
{
 
114
    return m_textCheckerClient.isContinousSpellCheckingEnabled();
 
115
}
 
116
 
 
117
bool EditorClientQt::isGrammarCheckingEnabled()
 
118
{
 
119
    return m_textCheckerClient.isGrammarCheckingEnabled();
 
120
}
 
121
 
 
122
int EditorClientQt::spellCheckerDocumentTag()
 
123
{
 
124
    return 0;
 
125
}
 
126
 
 
127
bool EditorClientQt::shouldBeginEditing(WebCore::Range* range)
 
128
{
 
129
    if (dumpEditingCallbacks)
 
130
        printf("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n", dumpRange(range).toUtf8().constData());
 
131
    return true;
 
132
}
 
133
 
 
134
bool EditorClientQt::shouldEndEditing(WebCore::Range* range)
 
135
{
 
136
    if (dumpEditingCallbacks)
 
137
        printf("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n", dumpRange(range).toUtf8().constData());
 
138
    return true;
 
139
}
 
140
 
 
141
bool EditorClientQt::shouldInsertText(const String& string, Range* range, EditorInsertAction action)
 
142
{
 
143
    if (dumpEditingCallbacks) {
 
144
        static const char *insertactionstring[] = {
 
145
            "WebViewInsertActionTyped",
 
146
            "WebViewInsertActionPasted",
 
147
            "WebViewInsertActionDropped",
 
148
        };
 
149
 
 
150
        printf("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n",
 
151
               QString(string).toUtf8().constData(), dumpRange(range).toUtf8().constData(), insertactionstring[action]);
 
152
    }
 
153
    return acceptsEditing;
 
154
}
 
155
 
 
156
bool EditorClientQt::shouldChangeSelectedRange(Range* currentRange, Range* proposedRange, EAffinity selectionAffinity, bool stillSelecting)
 
157
{
 
158
    if (dumpEditingCallbacks) {
 
159
        static const char *affinitystring[] = {
 
160
            "NSSelectionAffinityUpstream",
 
161
            "NSSelectionAffinityDownstream"
 
162
        };
 
163
        static const char *boolstring[] = {
 
164
            "FALSE",
 
165
            "TRUE"
 
166
        };
 
167
 
 
168
        printf("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n",
 
169
               dumpRange(currentRange).toUtf8().constData(),
 
170
               dumpRange(proposedRange).toUtf8().constData(),
 
171
               affinitystring[selectionAffinity], boolstring[stillSelecting]);
 
172
    }
 
173
    return acceptsEditing;
 
174
}
 
175
 
 
176
bool EditorClientQt::shouldApplyStyle(WebCore::StylePropertySet* style,
 
177
                                      WebCore::Range* range)
 
178
{
 
179
    if (dumpEditingCallbacks)
 
180
        printf("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n",
 
181
               QString(style->asText()).toUtf8().constData(), dumpRange(range).toUtf8().constData());
 
182
    return acceptsEditing;
 
183
}
 
184
 
 
185
bool EditorClientQt::shouldMoveRangeAfterDelete(WebCore::Range*, WebCore::Range*)
 
186
{
 
187
    notImplemented();
 
188
    return true;
 
189
}
 
190
 
 
191
void EditorClientQt::didBeginEditing()
 
192
{
 
193
    if (dumpEditingCallbacks)
 
194
        printf("EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification\n");
 
195
    m_editing = true;
 
196
}
 
197
 
 
198
void EditorClientQt::respondToChangedContents()
 
199
{
 
200
    if (dumpEditingCallbacks)
 
201
        printf("EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification\n");
 
202
    m_page->d->updateEditorActions();
 
203
 
 
204
    emit m_page->contentsChanged();
 
205
}
 
206
 
 
207
void EditorClientQt::respondToChangedSelection(Frame* frame)
 
208
{
 
209
    if (dumpEditingCallbacks)
 
210
        printf("EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification\n");
 
211
//     const Selection &selection = m_page->d->page->selection();
 
212
//     char buffer[1024];
 
213
//     selection.formatForDebugger(buffer, sizeof(buffer));
 
214
//     printf("%s\n", buffer);
 
215
 
 
216
    if (supportsGlobalSelection() && frame->selection()->isRange()) {
 
217
        bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode();
 
218
        Pasteboard::generalPasteboard()->setSelectionMode(true);
 
219
        Pasteboard::generalPasteboard()->writeSelection(frame->selection()->toNormalizedRange().get(), frame->editor()->canSmartCopyOrDelete(), frame);
 
220
        Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode);
 
221
    }
 
222
 
 
223
    m_page->d->updateEditorActions();
 
224
    emit m_page->selectionChanged();
 
225
    if (!frame->editor()->ignoreCompositionSelectionChange())
 
226
        emit m_page->microFocusChanged();
 
227
}
 
228
 
 
229
void EditorClientQt::didEndEditing()
 
230
{
 
231
    if (dumpEditingCallbacks)
 
232
        printf("EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification\n");
 
233
    m_editing = false;
 
234
}
 
235
 
 
236
void EditorClientQt::didWriteSelectionToPasteboard()
 
237
{
 
238
}
 
239
 
 
240
void EditorClientQt::didSetSelectionTypesForPasteboard()
 
241
{
 
242
}
 
243
 
 
244
bool EditorClientQt::selectWordBeforeMenuEvent()
 
245
{
 
246
    notImplemented();
 
247
    return false;
 
248
}
 
249
 
 
250
void EditorClientQt::registerUndoStep(WTF::PassRefPtr<WebCore::UndoStep> step)
 
251
{
 
252
#ifndef QT_NO_UNDOSTACK
 
253
    Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame();
 
254
    if (m_inUndoRedo || (frame && !frame->editor()->lastEditCommand() /* HACK!! Don't recreate undos */))
 
255
        return;
 
256
    m_page->undoStack()->push(new UndoStepQt(step));
 
257
#endif // QT_NO_UNDOSTACK
 
258
}
 
259
 
 
260
void EditorClientQt::registerRedoStep(WTF::PassRefPtr<WebCore::UndoStep>)
 
261
{
 
262
}
 
263
 
 
264
void EditorClientQt::clearUndoRedoOperations()
 
265
{
 
266
#ifndef QT_NO_UNDOSTACK
 
267
    return m_page->undoStack()->clear();
 
268
#endif
 
269
}
 
270
 
 
271
bool EditorClientQt::canCopyCut(WebCore::Frame*, bool defaultValue) const
 
272
{
 
273
    return defaultValue;
 
274
}
 
275
 
 
276
bool EditorClientQt::canPaste(WebCore::Frame*, bool defaultValue) const
 
277
{
 
278
    return defaultValue;
 
279
}
 
280
 
 
281
bool EditorClientQt::canUndo() const
 
282
{
 
283
#ifdef QT_NO_UNDOSTACK
 
284
    return false;
 
285
#else
 
286
    return m_page->undoStack()->canUndo();
 
287
#endif
 
288
}
 
289
 
 
290
bool EditorClientQt::canRedo() const
 
291
{
 
292
#ifdef QT_NO_UNDOSTACK
 
293
    return false;
 
294
#else
 
295
    return m_page->undoStack()->canRedo();
 
296
#endif
 
297
}
 
298
 
 
299
void EditorClientQt::undo()
 
300
{
 
301
#ifndef QT_NO_UNDOSTACK
 
302
    m_inUndoRedo = true;
 
303
    m_page->undoStack()->undo();
 
304
    m_inUndoRedo = false;
 
305
#endif
 
306
}
 
307
 
 
308
void EditorClientQt::redo()
 
309
{
 
310
#ifndef QT_NO_UNDOSTACK
 
311
    m_inUndoRedo = true;
 
312
    m_page->undoStack()->redo();
 
313
    m_inUndoRedo = false;
 
314
#endif
 
315
}
 
316
 
 
317
bool EditorClientQt::shouldInsertNode(Node* node, Range* range, EditorInsertAction action)
 
318
{
 
319
    if (dumpEditingCallbacks) {
 
320
        static const char *insertactionstring[] = {
 
321
            "WebViewInsertActionTyped",
 
322
            "WebViewInsertActionPasted",
 
323
            "WebViewInsertActionDropped",
 
324
        };
 
325
 
 
326
        printf("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n", dumpPath(node).toUtf8().constData(),
 
327
               dumpRange(range).toUtf8().constData(), insertactionstring[action]);
 
328
    }
 
329
    return acceptsEditing;
 
330
}
 
331
 
 
332
void EditorClientQt::pageDestroyed()
 
333
{
 
334
    delete this;
 
335
}
 
336
 
 
337
bool EditorClientQt::smartInsertDeleteEnabled()
 
338
{
 
339
    return m_page->d->smartInsertDeleteEnabled;
 
340
}
 
341
 
 
342
void EditorClientQt::toggleSmartInsertDelete()
 
343
{
 
344
    bool current = m_page->d->smartInsertDeleteEnabled;
 
345
    m_page->d->smartInsertDeleteEnabled = !current;
 
346
}
 
347
 
 
348
bool EditorClientQt::isSelectTrailingWhitespaceEnabled()
 
349
{
 
350
    return m_page->d->selectTrailingWhitespaceEnabled;
 
351
}
 
352
 
 
353
void EditorClientQt::toggleContinuousSpellChecking()
 
354
{
 
355
    m_textCheckerClient.toggleContinousSpellChecking();
 
356
}
 
357
 
 
358
void EditorClientQt::toggleGrammarChecking()
 
359
{
 
360
    return m_textCheckerClient.toggleGrammarChecking();
 
361
}
 
362
 
 
363
static const unsigned CtrlKey = 1 << 0;
 
364
static const unsigned AltKey = 1 << 1;
 
365
static const unsigned ShiftKey = 1 << 2;
 
366
 
 
367
struct KeyDownEntry {
 
368
    unsigned virtualKey;
 
369
    unsigned modifiers;
 
370
    const char* editorCommand;
 
371
};
 
372
 
 
373
// Handle here key down events that are needed for spatial navigation and caret browsing, or
 
374
// are not handled by QWebPage.
 
375
static const KeyDownEntry keyDownEntries[] = {
 
376
    // Ones that do not have an associated QAction:
 
377
    { VK_DELETE, 0,                  "DeleteForward"                     },
 
378
    { VK_BACK,   ShiftKey,           "DeleteBackward"                    },
 
379
    { VK_BACK,   0,                  "DeleteBackward"                    },
 
380
    // Ones that need special handling for caret browsing:
 
381
    { VK_PRIOR,  0,                  "MovePageUp"                        },
 
382
    { VK_PRIOR,  ShiftKey,           "MovePageUpAndModifySelection"      },
 
383
    { VK_NEXT,   0,                  "MovePageDown"                      },
 
384
    { VK_NEXT,   ShiftKey,           "MovePageDownAndModifySelection"    },
 
385
    // Ones that need special handling for spatial navigation:
 
386
    { VK_LEFT,   0,                  "MoveLeft"                          },
 
387
    { VK_RIGHT,  0,                  "MoveRight"                         },
 
388
    { VK_UP,     0,                  "MoveUp"                            },
 
389
    { VK_DOWN,   0,                  "MoveDown"                          },
 
390
};
 
391
 
 
392
const char* editorCommandForKeyDownEvent(const KeyboardEvent* event)
 
393
{
 
394
    if (event->type() != eventNames().keydownEvent)
 
395
        return "";
 
396
 
 
397
    static HashMap<int, const char*> keyDownCommandsMap;
 
398
    if (keyDownCommandsMap.isEmpty()) {
 
399
 
 
400
        unsigned numEntries = sizeof(keyDownEntries) / sizeof((keyDownEntries)[0]);
 
401
        for (unsigned i = 0; i < numEntries; i++)
 
402
            keyDownCommandsMap.set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].editorCommand);
 
403
    }
 
404
 
 
405
    unsigned modifiers = 0;
 
406
    if (event->shiftKey())
 
407
        modifiers |= ShiftKey;
 
408
    if (event->altKey())
 
409
        modifiers |= AltKey;
 
410
    if (event->ctrlKey())
 
411
        modifiers |= CtrlKey;
 
412
 
 
413
    int mapKey = modifiers << 16 | event->keyCode();
 
414
    return mapKey ? keyDownCommandsMap.get(mapKey) : 0;
 
415
}
 
416
 
 
417
void EditorClientQt::handleKeyboardEvent(KeyboardEvent* event)
 
418
{
 
419
    Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame();
 
420
    if (!frame)
 
421
        return;
 
422
 
 
423
    const PlatformKeyboardEvent* kevent = event->keyEvent();
 
424
    if (!kevent || kevent->type() == PlatformEvent::KeyUp)
 
425
        return;
 
426
 
 
427
    Node* start = frame->selection()->start().containerNode();
 
428
    if (!start)
 
429
        return;
 
430
 
 
431
    // FIXME: refactor all of this to use Actions or something like them
 
432
    if (start->isContentEditable()) {
 
433
        bool doSpatialNavigation = false;
 
434
        if (isSpatialNavigationEnabled(frame)) {
 
435
            if (!kevent->modifiers()) {
 
436
                switch (kevent->windowsVirtualKeyCode()) {
 
437
                case VK_LEFT:
 
438
                case VK_RIGHT:
 
439
                case VK_UP:
 
440
                case VK_DOWN:
 
441
                    doSpatialNavigation = true;
 
442
                }
 
443
            }
 
444
        }
 
445
 
 
446
#ifndef QT_NO_SHORTCUT
 
447
        QWebPage::WebAction action = QWebPagePrivate::editorActionForKeyEvent(kevent->qtEvent());
 
448
        if (action != QWebPage::NoWebAction && !doSpatialNavigation) {
 
449
            const char* cmd = QWebPagePrivate::editorCommandForWebActions(action);
 
450
            // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
 
451
            // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
 
452
            // (e.g. Tab that inserts a Tab character, or Enter).
 
453
            if (cmd && frame->editor()->command(cmd).isTextInsertion()
 
454
                && kevent->type() == PlatformEvent::RawKeyDown)
 
455
                return;
 
456
 
 
457
            m_page->triggerAction(action);
 
458
            event->setDefaultHandled();
 
459
            return;
 
460
        } else 
 
461
#endif // QT_NO_SHORTCUT
 
462
        {
 
463
            String commandName = editorCommandForKeyDownEvent(event);
 
464
            if (!commandName.isEmpty()) {
 
465
                if (frame->editor()->command(commandName).execute()) // Event handled.
 
466
                    event->setDefaultHandled();
 
467
                return;
 
468
            }
 
469
 
 
470
            if (kevent->windowsVirtualKeyCode() == VK_TAB) {
 
471
                // Do not handle TAB text insertion here.
 
472
                return;
 
473
            }
 
474
 
 
475
            // Text insertion.
 
476
            bool shouldInsertText = false;
 
477
            if (kevent->type() != PlatformEvent::KeyDown && !kevent->text().isEmpty()) {
 
478
 
 
479
                if (kevent->ctrlKey()) {
 
480
                    if (kevent->altKey())
 
481
                        shouldInsertText = true;
 
482
                } else {
 
483
#ifndef Q_WS_MAC
 
484
                // We need to exclude checking for Alt because it is just a different Shift
 
485
                if (!kevent->altKey())
 
486
#endif
 
487
                    shouldInsertText = true;
 
488
 
 
489
                }
 
490
            }
 
491
 
 
492
            if (shouldInsertText) {
 
493
                frame->editor()->insertText(kevent->text(), event);
 
494
                event->setDefaultHandled();
 
495
                return;
 
496
            }
 
497
        }
 
498
 
 
499
        // Event not handled.
 
500
        return;
 
501
    }
 
502
 
 
503
    // Non editable content.
 
504
    if (m_page->handle()->page->settings()->caretBrowsingEnabled()) {
 
505
        switch (kevent->windowsVirtualKeyCode()) {
 
506
        case VK_LEFT:
 
507
        case VK_RIGHT:
 
508
        case VK_UP:
 
509
        case VK_DOWN:
 
510
        case VK_HOME:
 
511
        case VK_END:
 
512
            {
 
513
#ifndef QT_NO_SHORTCUT
 
514
                QWebPage::WebAction action = QWebPagePrivate::editorActionForKeyEvent(kevent->qtEvent());
 
515
                ASSERT(action != QWebPage::NoWebAction);
 
516
                m_page->triggerAction(action);
 
517
                event->setDefaultHandled();
 
518
#endif
 
519
                return;
 
520
            }
 
521
        case VK_PRIOR: // PageUp
 
522
        case VK_NEXT:  // PageDown
 
523
            {
 
524
                String commandName = editorCommandForKeyDownEvent(event);
 
525
                ASSERT(!commandName.isEmpty());
 
526
                frame->editor()->command(commandName).execute();
 
527
                event->setDefaultHandled();
 
528
                return;
 
529
            }
 
530
        }
 
531
    }
 
532
 
 
533
#ifndef QT_NO_SHORTCUT
 
534
    if (kevent->qtEvent() == QKeySequence::Copy) {
 
535
        m_page->triggerAction(QWebPage::Copy);
 
536
        event->setDefaultHandled();
 
537
        return;
 
538
    }
 
539
#endif // QT_NO_SHORTCUT
 
540
}
 
541
 
 
542
void EditorClientQt::handleInputMethodKeydown(KeyboardEvent*)
 
543
{
 
544
}
 
545
 
 
546
EditorClientQt::EditorClientQt(QWebPage* page)
 
547
    : m_page(page), m_editing(false), m_inUndoRedo(false)
 
548
{
 
549
}
 
550
 
 
551
void EditorClientQt::textFieldDidBeginEditing(Element*)
 
552
{
 
553
    m_editing = true;
 
554
}
 
555
 
 
556
void EditorClientQt::textFieldDidEndEditing(Element*)
 
557
{
 
558
    m_editing = false;
 
559
}
 
560
 
 
561
void EditorClientQt::textDidChangeInTextField(Element*)
 
562
{
 
563
}
 
564
 
 
565
bool EditorClientQt::doTextFieldCommandFromEvent(Element*, KeyboardEvent*)
 
566
{
 
567
    return false;
 
568
}
 
569
 
 
570
void EditorClientQt::textWillBeDeletedInTextField(Element*)
 
571
{
 
572
}
 
573
 
 
574
void EditorClientQt::textDidChangeInTextArea(Element*)
 
575
{
 
576
}
 
577
 
 
578
void EditorClientQt::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&)
 
579
{
 
580
    notImplemented();
 
581
}
 
582
 
 
583
void EditorClientQt::updateSpellingUIWithMisspelledWord(const String&)
 
584
{
 
585
    notImplemented();
 
586
}
 
587
 
 
588
void EditorClientQt::showSpellingUI(bool)
 
589
{
 
590
    notImplemented();
 
591
}
 
592
 
 
593
bool EditorClientQt::spellingUIIsShowing()
 
594
{
 
595
    notImplemented();
 
596
    return false;
 
597
}
 
598
 
 
599
bool EditorClientQt::isEditing() const
 
600
{
 
601
    return m_editing;
 
602
}
 
603
 
 
604
void EditorClientQt::willSetInputMethodState()
 
605
{
 
606
}
 
607
 
 
608
void EditorClientQt::setInputMethodState(bool active)
 
609
{
 
610
    QWebPageClient* webPageClient = m_page->d->client.get();
 
611
    if (webPageClient) {
 
612
        Qt::InputMethodHints hints;
 
613
 
 
614
        HTMLInputElement* inputElement = 0;
 
615
        Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame();
 
616
        if (frame && frame->document() && frame->document()->focusedNode())
 
617
            if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag))
 
618
                inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode());
 
619
 
 
620
        if (inputElement) {
 
621
            // Set input method hints for "number", "tel", "email", "url" and "password" input elements.
 
622
            if (inputElement->isTelephoneField())
 
623
                hints |= Qt::ImhDialableCharactersOnly;
 
624
            if (inputElement->isNumberField())
 
625
                hints |= Qt::ImhDigitsOnly;
 
626
            if (inputElement->isEmailField())
 
627
                hints |= Qt::ImhEmailCharactersOnly;
 
628
            if (inputElement->isURLField())
 
629
                hints |= Qt::ImhUrlCharactersOnly;
 
630
            // Setting the Qt::WA_InputMethodEnabled attribute true and Qt::ImhHiddenText flag
 
631
            // for password fields. The Qt platform is responsible for determining which widget
 
632
            // will receive input method events for password fields.
 
633
            if (inputElement->isPasswordField()) {
 
634
                active = true;
 
635
                hints |= Qt::ImhHiddenText;
 
636
            }
 
637
        }
 
638
 
 
639
        webPageClient->setInputMethodHints(hints);
 
640
        webPageClient->setInputMethodEnabled(active);
 
641
    }
 
642
    emit m_page->microFocusChanged();
 
643
}
 
644
 
 
645
bool EditorClientQt::supportsGlobalSelection()
 
646
{
 
647
#ifndef QT_NO_CLIPBOARD
 
648
    return qApp->clipboard()->supportsSelection();
 
649
#else
 
650
    return false;
 
651
#endif
 
652
}
 
653
 
 
654
}
 
655
 
 
656
// vim: ts=4 sw=4 et