1/*
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef InputMethodController_h
27#define InputMethodController_h
28
29#include "core/editing/CompositionUnderline.h"
30#include "core/editing/PlainTextRange.h"
31#include "platform/heap/Handle.h"
32#include "wtf/Vector.h"
33
34namespace blink {
35
36class Editor;
37class LocalFrame;
38class Range;
39class Text;
40
41class InputMethodController FINAL : public NoBaseWillBeGarbageCollectedFinalized<InputMethodController> {
42    WTF_MAKE_NONCOPYABLE(InputMethodController);
43public:
44    enum ConfirmCompositionBehavior {
45        DoNotKeepSelection,
46        KeepSelection,
47    };
48
49    static PassOwnPtrWillBeRawPtr<InputMethodController> create(LocalFrame&);
50    ~InputMethodController();
51    void trace(Visitor*);
52
53    // international text input composition
54    bool hasComposition() const;
55    void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd);
56    void setCompositionFromExistingText(const Vector<CompositionUnderline>&, unsigned compositionStart, unsigned compositionEnd);
57    // Inserts the text that is being composed as a regular text and returns true
58    // if composition exists.
59    bool confirmComposition();
60    // Inserts the given text string in the place of the existing composition
61    // and returns true.
62    bool confirmComposition(const String& text);
63    // Inserts the text that is being composed or specified non-empty text and
64    // returns true.
65    bool confirmCompositionOrInsertText(const String& text, ConfirmCompositionBehavior);
66    void confirmCompositionAndResetState();
67    // Deletes the existing composition text.
68    void cancelComposition();
69    void cancelCompositionIfSelectionIsInvalid();
70    PassRefPtrWillBeRawPtr<Range> compositionRange() const;
71
72    // getting international text input composition state (for use by InlineTextBox)
73    Text* compositionNode() const { return m_compositionNode.get(); }
74    unsigned compositionStart() const { return m_compositionStart; }
75    unsigned compositionEnd() const { return m_compositionEnd; }
76    bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); }
77    const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; }
78
79    void clear();
80
81    PlainTextRange getSelectionOffsets() const;
82    // Returns true if setting selection to specified offsets, otherwise false.
83    bool setEditableSelectionOffsets(const PlainTextRange&);
84    void extendSelectionAndDelete(int before, int after);
85
86private:
87    class SelectionOffsetsScope {
88        WTF_MAKE_NONCOPYABLE(SelectionOffsetsScope);
89    public:
90        SelectionOffsetsScope(InputMethodController*);
91        ~SelectionOffsetsScope();
92    private:
93        InputMethodController* m_inputMethodController;
94        const PlainTextRange m_offsets;
95    };
96    friend class SelectionOffsetsScope;
97
98    RawPtrWillBeMember<LocalFrame> m_frame;
99    RefPtrWillBeMember<Text> m_compositionNode;
100    // We don't use PlainTextRange which is immutable, for composition range.
101    unsigned m_compositionStart;
102    unsigned m_compositionEnd;
103    // startOffset and endOffset of CompositionUnderline are based on
104    // m_compositionNode.
105    Vector<CompositionUnderline> m_customCompositionUnderlines;
106
107    explicit InputMethodController(LocalFrame&);
108
109    Editor& editor() const;
110    LocalFrame& frame() const
111    {
112        ASSERT(m_frame);
113        return *m_frame;
114    }
115
116    bool insertTextForConfirmedComposition(const String& text);
117    void selectComposition() const;
118    enum FinishCompositionMode { ConfirmComposition, CancelComposition };
119    // Returns true if composition exists.
120    bool finishComposition(const String&, FinishCompositionMode);
121    bool setSelectionOffsets(const PlainTextRange&);
122};
123
124} // namespace blink
125
126#endif // InputMethodController_h
127