ExtractEditText.java revision dbd25cdbc3dcad573aaeaf493bc186006bce3d8e
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.inputmethodservice;
18
19import android.content.Context;
20import android.util.AttributeSet;
21import android.view.ContextMenu;
22import android.view.inputmethod.ExtractedText;
23import android.widget.EditText;
24
25/***
26 * Specialization of {@link EditText} for showing and interacting with the
27 * extracted text in a full-screen input method.
28 */
29public class ExtractEditText extends EditText {
30    private InputMethodService mIME;
31    private int mSettingExtractedText;
32    private boolean mContextMenuShouldBeHandledBySuper = false;
33
34    public ExtractEditText(Context context) {
35        super(context, null);
36    }
37
38    public ExtractEditText(Context context, AttributeSet attrs) {
39        super(context, attrs, com.android.internal.R.attr.editTextStyle);
40    }
41
42    public ExtractEditText(Context context, AttributeSet attrs, int defStyle) {
43        super(context, attrs, defStyle);
44    }
45
46    void setIME(InputMethodService ime) {
47        mIME = ime;
48    }
49
50    /**
51     * Start making changes that will not be reported to the client.  That
52     * is, {@link #onSelectionChanged(int, int)} will not result in sending
53     * the new selection to the client
54     */
55    public void startInternalChanges() {
56        mSettingExtractedText += 1;
57    }
58
59    /**
60     * Finish making changes that will not be reported to the client.  That
61     * is, {@link #onSelectionChanged(int, int)} will not result in sending
62     * the new selection to the client
63     */
64    public void finishInternalChanges() {
65        mSettingExtractedText -= 1;
66    }
67
68    /**
69     * Implement just to keep track of when we are setting text from the
70     * client (vs. seeing changes in ourself from the user).
71     */
72    @Override public void setExtractedText(ExtractedText text) {
73        try {
74            mSettingExtractedText++;
75            super.setExtractedText(text);
76        } finally {
77            mSettingExtractedText--;
78        }
79    }
80
81    /**
82     * Report to the underlying text editor about selection changes.
83     */
84    @Override protected void onSelectionChanged(int selStart, int selEnd) {
85        if (mSettingExtractedText == 0 && mIME != null && selStart >= 0 && selEnd >= 0) {
86            mIME.onExtractedSelectionChanged(selStart, selEnd);
87        }
88    }
89
90    /**
91     * Redirect clicks to the IME for handling there.  First allows any
92     * on click handler to run, though.
93     */
94    @Override public boolean performClick() {
95        if (!super.performClick() && mIME != null) {
96            mIME.onExtractedTextClicked();
97            return true;
98        }
99        return false;
100    }
101
102    @Override
103    protected void onCreateContextMenu(ContextMenu menu) {
104        super.onCreateContextMenu(menu);
105        mContextMenuShouldBeHandledBySuper = true;
106    }
107
108    @Override public boolean onTextContextMenuItem(int id) {
109        if (mIME != null && !mContextMenuShouldBeHandledBySuper) {
110            if (mIME.onExtractTextContextMenuItem(id)) {
111                return true;
112            }
113        }
114        mContextMenuShouldBeHandledBySuper = false;
115        return super.onTextContextMenuItem(id);
116    }
117
118    /**
119     * We are always considered to be an input method target.
120     */
121    @Override
122    public boolean isInputMethodTarget() {
123        return true;
124    }
125
126    /**
127     * Return true if the edit text is currently showing a scroll bar.
128     */
129    public boolean hasVerticalScrollBar() {
130        return computeVerticalScrollRange() > computeVerticalScrollExtent();
131    }
132
133    /**
134     * Pretend like the window this view is in always has focus, so its
135     * highlight and cursor will be displayed.
136     */
137    @Override public boolean hasWindowFocus() {
138        return this.isEnabled();
139    }
140
141    /**
142     * Pretend like this view always has focus, so its
143     * highlight and cursor will be displayed.
144     */
145    @Override public boolean isFocused() {
146        return this.isEnabled();
147    }
148
149    /**
150     * Pretend like this view always has focus, so its
151     * highlight and cursor will be displayed.
152     */
153    @Override public boolean hasFocus() {
154        return this.isEnabled();
155    }
156}
157