blob: 964695290417c008959427663ffad95b7d745f69 [file] [log] [blame]
The Android Open Source Project0c908882009-03-03 19:32:16 -08001/*
2 * Copyright (C) 2007 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 com.android.browser;
18
The Android Open Source Project0c908882009-03-03 19:32:16 -080019import android.content.Context;
The Android Open Source Project0c908882009-03-03 19:32:16 -080020import android.text.Editable;
Leon Scroggins III36529cf2010-05-06 13:34:28 -040021import android.text.Selection;
The Android Open Source Project0c908882009-03-03 19:32:16 -080022import android.text.Spannable;
23import android.text.TextWatcher;
24import android.view.Gravity;
25import android.view.KeyEvent;
Leon Scroggins III211ba542010-04-19 13:21:13 -040026import android.view.LayoutInflater;
The Android Open Source Project0c908882009-03-03 19:32:16 -080027import android.view.View;
28import android.view.ViewGroup;
Leon Scroggins III211ba542010-04-19 13:21:13 -040029import android.view.animation.AnimationUtils;
The Android Open Source Project0c908882009-03-03 19:32:16 -080030import android.view.inputmethod.InputMethodManager;
31import android.webkit.WebView;
32import android.widget.EditText;
Leon Scroggins III211ba542010-04-19 13:21:13 -040033import android.widget.LinearLayout;
The Android Open Source Project0c908882009-03-03 19:32:16 -080034import android.widget.TextView;
35
Leon Scroggins III211ba542010-04-19 13:21:13 -040036/* package */ class FindDialog extends LinearLayout implements TextWatcher {
The Android Open Source Project0c908882009-03-03 19:32:16 -080037 private WebView mWebView;
38 private TextView mMatches;
39 private BrowserActivity mBrowserActivity;
40
41 // Views with which the user can interact.
The Android Open Source Project0c908882009-03-03 19:32:16 -080042 private EditText mEditText;
43 private View mNextButton;
44 private View mPrevButton;
45 private View mMatchesView;
46
Leon Scroggins III36529cf2010-05-06 13:34:28 -040047 // When the dialog is opened up with old text, enter needs to be pressed
48 // (or the text needs to be changed) before WebView.findAll can be called.
49 // Once it has been called, enter should move to the next match.
50 private boolean mMatchesFound;
The Android Open Source Project0c908882009-03-03 19:32:16 -080051 private View.OnClickListener mFindListener = new View.OnClickListener() {
52 public void onClick(View v) {
53 findNext();
54 }
55 };
56
57 private View.OnClickListener mFindCancelListener =
58 new View.OnClickListener() {
59 public void onClick(View v) {
Leon Scroggins III211ba542010-04-19 13:21:13 -040060 mBrowserActivity.closeFind();
The Android Open Source Project0c908882009-03-03 19:32:16 -080061 }
62 };
63
64 private View.OnClickListener mFindPreviousListener =
65 new View.OnClickListener() {
66 public void onClick(View v) {
67 if (mWebView == null) {
68 throw new AssertionError("No WebView for FindDialog::onClick");
69 }
70 mWebView.findNext(false);
71 hideSoftInput();
72 }
73 };
74
75 /*
76 * Remove the soft keyboard from the screen.
77 */
78 private void hideSoftInput() {
79 InputMethodManager imm = (InputMethodManager)
80 mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
81 imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
82 }
83
84 private void disableButtons() {
85 mPrevButton.setEnabled(false);
86 mNextButton.setEnabled(false);
87 mPrevButton.setFocusable(false);
88 mNextButton.setFocusable(false);
89 }
90
91 /* package */ void setWebView(WebView webview) {
92 mWebView = webview;
93 }
94
95 /* package */ FindDialog(BrowserActivity context) {
Leon Scroggins III211ba542010-04-19 13:21:13 -040096 super(context);
The Android Open Source Project0c908882009-03-03 19:32:16 -080097 mBrowserActivity = context;
The Android Open Source Project0c908882009-03-03 19:32:16 -080098
Leon Scroggins III211ba542010-04-19 13:21:13 -040099 LayoutInflater factory = LayoutInflater.from(context);
100 factory.inflate(R.layout.browser_find, this);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800101
102 mEditText = (EditText) findViewById(R.id.edit);
103
104 View button = findViewById(R.id.next);
105 button.setOnClickListener(mFindListener);
106 mNextButton = button;
107
108 button = findViewById(R.id.previous);
109 button.setOnClickListener(mFindPreviousListener);
110 mPrevButton = button;
111
112 button = findViewById(R.id.done);
113 button.setOnClickListener(mFindCancelListener);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800114
115 mMatches = (TextView) findViewById(R.id.matches);
116 mMatchesView = findViewById(R.id.matches_view);
117 disableButtons();
Leon Scroggins III211ba542010-04-19 13:21:13 -0400118
The Android Open Source Project0c908882009-03-03 19:32:16 -0800119 }
Leon Scroggins III211ba542010-04-19 13:21:13 -0400120
121 /**
122 * Called by BrowserActivity.closeFind. Start the animation to hide
123 * the dialog, inform the WebView that the dialog is being dismissed,
124 * and hide the soft keyboard.
125 */
The Android Open Source Project0c908882009-03-03 19:32:16 -0800126 public void dismiss() {
Cary Clark7d3ac792010-03-03 10:11:44 -0500127 mWebView.notifyFindDialogDismissed();
Leon Scroggins III211ba542010-04-19 13:21:13 -0400128 startAnimation(AnimationUtils.loadAnimation(mBrowserActivity,
129 R.anim.find_dialog_exit));
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400130 hideSoftInput();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800131 }
Leon Scroggins354bbd02009-04-16 15:24:07 -0400132
The Android Open Source Project0c908882009-03-03 19:32:16 -0800133 @Override
Leon Scroggins IIIcda86002010-05-06 14:27:07 -0400134 public boolean dispatchKeyEventPreIme(KeyEvent event) {
135 if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
136 KeyEvent.DispatcherState state = getKeyDispatcherState();
137 if (state != null) {
138 int action = event.getAction();
139 if (KeyEvent.ACTION_DOWN == action
140 && event.getRepeatCount() == 0) {
141 state.startTracking(event, this);
142 return true;
143 } else if (KeyEvent.ACTION_UP == action
144 && !event.isCanceled() && state.isTracking(event)) {
145 mBrowserActivity.closeFind();
146 return true;
147 }
148 }
149 }
150 return super.dispatchKeyEventPreIme(event);
151 }
152
153 @Override
The Android Open Source Project0c908882009-03-03 19:32:16 -0800154 public boolean dispatchKeyEvent(KeyEvent event) {
Leon Scroggins III211ba542010-04-19 13:21:13 -0400155 int keyCode = event.getKeyCode();
Leon Scroggins IIIcda86002010-05-06 14:27:07 -0400156 if (event.getAction() == KeyEvent.ACTION_UP) {
Leon Scroggins III211ba542010-04-19 13:21:13 -0400157 if (keyCode == KeyEvent.KEYCODE_ENTER
158 && mEditText.hasFocus()) {
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400159 if (mMatchesFound) {
160 findNext();
161 } else {
162 findAll();
163 // Set the selection to the end.
164 Spannable span = (Spannable) mEditText.getText();
165 Selection.setSelection(span, span.length());
166 }
Leon Scroggins III211ba542010-04-19 13:21:13 -0400167 return true;
168 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800169 }
170 return super.dispatchKeyEvent(event);
171 }
172
173 private void findNext() {
174 if (mWebView == null) {
175 throw new AssertionError("No WebView for FindDialog::findNext");
176 }
177 mWebView.findNext(true);
178 hideSoftInput();
179 }
180
181 public void show() {
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400182 // In case the matches view is showing from a previous search
183 mMatchesView.setVisibility(View.INVISIBLE);
184 mMatchesFound = false;
The Android Open Source Project0c908882009-03-03 19:32:16 -0800185 mEditText.requestFocus();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800186 Spannable span = (Spannable) mEditText.getText();
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400187 int length = span.length();
188 Selection.setSelection(span, 0, length);
189 span.setSpan(this, 0, length, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
Eric Fischer8963b292009-03-24 17:53:52 -0700190 setMatchesFound(0);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800191 disableButtons();
Leon Scroggins III211ba542010-04-19 13:21:13 -0400192 startAnimation(AnimationUtils.loadAnimation(mBrowserActivity,
193 R.anim.find_dialog_enter));
194 InputMethodManager imm = (InputMethodManager)
195 mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
196 imm.showSoftInput(mEditText, 0);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800197 }
198
199 // TextWatcher methods
200 public void beforeTextChanged(CharSequence s,
201 int start,
202 int count,
203 int after) {
204 }
205
206 public void onTextChanged(CharSequence s,
207 int start,
208 int before,
209 int count) {
210 if (mWebView == null) {
211 throw new AssertionError(
212 "No WebView for FindDialog::onTextChanged");
213 }
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400214 findAll();
215 }
216
217 private void findAll() {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800218 CharSequence find = mEditText.getText();
219 if (0 == find.length()) {
220 disableButtons();
221 mWebView.clearMatches();
222 mMatchesView.setVisibility(View.INVISIBLE);
223 } else {
224 mMatchesView.setVisibility(View.VISIBLE);
225 int found = mWebView.findAll(find.toString());
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400226 mMatchesFound = true;
Eric Fischer8963b292009-03-24 17:53:52 -0700227 setMatchesFound(found);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800228 if (found < 2) {
229 disableButtons();
230 if (found == 0) {
Eric Fischer8963b292009-03-24 17:53:52 -0700231 setMatchesFound(0);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800232 }
233 } else {
234 mPrevButton.setFocusable(true);
235 mNextButton.setFocusable(true);
236 mPrevButton.setEnabled(true);
237 mNextButton.setEnabled(true);
238 }
239 }
240 }
241
Eric Fischer8963b292009-03-24 17:53:52 -0700242 private void setMatchesFound(int found) {
243 String template = mBrowserActivity.getResources().
244 getQuantityString(R.plurals.matches_found, found, found);
245
246 mMatches.setText(template);
247 }
248
The Android Open Source Project0c908882009-03-03 19:32:16 -0800249 public void afterTextChanged(Editable s) {
250 }
251}