blob: 9d0ac4b95453d72a419f89fd3d78ede1c6d93cab [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
Cary Clark01cfcdd2010-06-04 16:36:45 -040036/* package */ class FindDialog extends WebDialog implements TextWatcher {
The Android Open Source Project0c908882009-03-03 19:32:16 -080037 private TextView mMatches;
The Android Open Source Project0c908882009-03-03 19:32:16 -080038
39 // Views with which the user can interact.
The Android Open Source Project0c908882009-03-03 19:32:16 -080040 private EditText mEditText;
41 private View mNextButton;
42 private View mPrevButton;
43 private View mMatchesView;
44
Leon Scroggins III36529cf2010-05-06 13:34:28 -040045 // When the dialog is opened up with old text, enter needs to be pressed
46 // (or the text needs to be changed) before WebView.findAll can be called.
47 // Once it has been called, enter should move to the next match.
48 private boolean mMatchesFound;
Leon Scrogginsbff40382010-05-06 16:36:42 -040049 private int mNumberOfMatches;
Cary Clark01cfcdd2010-06-04 16:36:45 -040050
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
Cary Clark01cfcdd2010-06-04 16:36:45 -040057 private View.OnClickListener mFindPreviousListener =
The Android Open Source Project0c908882009-03-03 19:32:16 -080058 new View.OnClickListener() {
59 public void onClick(View v) {
60 if (mWebView == null) {
61 throw new AssertionError("No WebView for FindDialog::onClick");
62 }
63 mWebView.findNext(false);
Leon Scrogginsbff40382010-05-06 16:36:42 -040064 updateMatchesString();
The Android Open Source Project0c908882009-03-03 19:32:16 -080065 hideSoftInput();
66 }
67 };
68
The Android Open Source Project0c908882009-03-03 19:32:16 -080069 private void disableButtons() {
70 mPrevButton.setEnabled(false);
71 mNextButton.setEnabled(false);
72 mPrevButton.setFocusable(false);
73 mNextButton.setFocusable(false);
74 }
75
The Android Open Source Project0c908882009-03-03 19:32:16 -080076 /* package */ FindDialog(BrowserActivity context) {
Leon Scroggins III211ba542010-04-19 13:21:13 -040077 super(context);
The Android Open Source Project0c908882009-03-03 19:32:16 -080078
Leon Scroggins III211ba542010-04-19 13:21:13 -040079 LayoutInflater factory = LayoutInflater.from(context);
80 factory.inflate(R.layout.browser_find, this);
The Android Open Source Project0c908882009-03-03 19:32:16 -080081
Cary Clark01cfcdd2010-06-04 16:36:45 -040082 addCancel();
The Android Open Source Project0c908882009-03-03 19:32:16 -080083 mEditText = (EditText) findViewById(R.id.edit);
84
85 View button = findViewById(R.id.next);
86 button.setOnClickListener(mFindListener);
87 mNextButton = button;
88
89 button = findViewById(R.id.previous);
90 button.setOnClickListener(mFindPreviousListener);
91 mPrevButton = button;
92
The Android Open Source Project0c908882009-03-03 19:32:16 -080093 mMatches = (TextView) findViewById(R.id.matches);
94 mMatchesView = findViewById(R.id.matches_view);
95 disableButtons();
Leon Scroggins III211ba542010-04-19 13:21:13 -040096
The Android Open Source Project0c908882009-03-03 19:32:16 -080097 }
Leon Scroggins III211ba542010-04-19 13:21:13 -040098
99 /**
Cary Clark01cfcdd2010-06-04 16:36:45 -0400100 * Called by BrowserActivity.closeDialog. Start the animation to hide
Leon Scroggins III211ba542010-04-19 13:21:13 -0400101 * the dialog, inform the WebView that the dialog is being dismissed,
102 * and hide the soft keyboard.
103 */
The Android Open Source Project0c908882009-03-03 19:32:16 -0800104 public void dismiss() {
Cary Clark01cfcdd2010-06-04 16:36:45 -0400105 super.dismiss();
Cary Clark7d3ac792010-03-03 10:11:44 -0500106 mWebView.notifyFindDialogDismissed();
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400107 hideSoftInput();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800108 }
Leon Scroggins354bbd02009-04-16 15:24:07 -0400109
The Android Open Source Project0c908882009-03-03 19:32:16 -0800110 @Override
Leon Scroggins IIIcda86002010-05-06 14:27:07 -0400111 public boolean dispatchKeyEventPreIme(KeyEvent event) {
112 if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
113 KeyEvent.DispatcherState state = getKeyDispatcherState();
114 if (state != null) {
115 int action = event.getAction();
116 if (KeyEvent.ACTION_DOWN == action
117 && event.getRepeatCount() == 0) {
118 state.startTracking(event, this);
119 return true;
120 } else if (KeyEvent.ACTION_UP == action
121 && !event.isCanceled() && state.isTracking(event)) {
Cary Clark01cfcdd2010-06-04 16:36:45 -0400122 mBrowserActivity.closeDialogs();
Leon Scroggins IIIcda86002010-05-06 14:27:07 -0400123 return true;
124 }
125 }
126 }
127 return super.dispatchKeyEventPreIme(event);
128 }
129
130 @Override
The Android Open Source Project0c908882009-03-03 19:32:16 -0800131 public boolean dispatchKeyEvent(KeyEvent event) {
Leon Scroggins III211ba542010-04-19 13:21:13 -0400132 int keyCode = event.getKeyCode();
Leon Scroggins IIIcda86002010-05-06 14:27:07 -0400133 if (event.getAction() == KeyEvent.ACTION_UP) {
Leon Scroggins III211ba542010-04-19 13:21:13 -0400134 if (keyCode == KeyEvent.KEYCODE_ENTER
135 && mEditText.hasFocus()) {
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400136 if (mMatchesFound) {
137 findNext();
138 } else {
139 findAll();
140 // Set the selection to the end.
141 Spannable span = (Spannable) mEditText.getText();
142 Selection.setSelection(span, span.length());
143 }
Leon Scroggins III211ba542010-04-19 13:21:13 -0400144 return true;
145 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800146 }
147 return super.dispatchKeyEvent(event);
148 }
149
150 private void findNext() {
151 if (mWebView == null) {
152 throw new AssertionError("No WebView for FindDialog::findNext");
153 }
154 mWebView.findNext(true);
Leon Scrogginsbff40382010-05-06 16:36:42 -0400155 updateMatchesString();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800156 hideSoftInput();
157 }
158
159 public void show() {
Cary Clark01cfcdd2010-06-04 16:36:45 -0400160 super.show();
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400161 // In case the matches view is showing from a previous search
162 mMatchesView.setVisibility(View.INVISIBLE);
163 mMatchesFound = false;
Leon Scrogginsbff40382010-05-06 16:36:42 -0400164 // This text is only here to ensure that mMatches has a height.
165 mMatches.setText("0");
The Android Open Source Project0c908882009-03-03 19:32:16 -0800166 mEditText.requestFocus();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800167 Spannable span = (Spannable) mEditText.getText();
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400168 int length = span.length();
169 Selection.setSelection(span, 0, length);
170 span.setSpan(this, 0, length, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800171 disableButtons();
Leon Scroggins III211ba542010-04-19 13:21:13 -0400172 InputMethodManager imm = (InputMethodManager)
173 mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
174 imm.showSoftInput(mEditText, 0);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800175 }
176
177 // TextWatcher methods
178 public void beforeTextChanged(CharSequence s,
179 int start,
180 int count,
181 int after) {
182 }
183
184 public void onTextChanged(CharSequence s,
185 int start,
186 int before,
187 int count) {
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400188 findAll();
189 }
190
191 private void findAll() {
Leon Scrogginsbff40382010-05-06 16:36:42 -0400192 if (mWebView == null) {
193 throw new AssertionError(
194 "No WebView for FindDialog::findAll");
195 }
The Android Open Source Project0c908882009-03-03 19:32:16 -0800196 CharSequence find = mEditText.getText();
197 if (0 == find.length()) {
198 disableButtons();
199 mWebView.clearMatches();
200 mMatchesView.setVisibility(View.INVISIBLE);
201 } else {
202 mMatchesView.setVisibility(View.VISIBLE);
203 int found = mWebView.findAll(find.toString());
Leon Scroggins III36529cf2010-05-06 13:34:28 -0400204 mMatchesFound = true;
Eric Fischer8963b292009-03-24 17:53:52 -0700205 setMatchesFound(found);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800206 if (found < 2) {
207 disableButtons();
208 if (found == 0) {
Leon Scrogginsbff40382010-05-06 16:36:42 -0400209 // Cannot use getQuantityString, which ignores the "zero"
210 // quantity.
211 mMatches.setText(mBrowserActivity.getResources().getString(
212 R.string.no_matches));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800213 }
214 } else {
215 mPrevButton.setFocusable(true);
216 mNextButton.setFocusable(true);
217 mPrevButton.setEnabled(true);
218 mNextButton.setEnabled(true);
219 }
220 }
221 }
222
Eric Fischer8963b292009-03-24 17:53:52 -0700223 private void setMatchesFound(int found) {
Leon Scrogginsbff40382010-05-06 16:36:42 -0400224 mNumberOfMatches = found;
225 updateMatchesString();
226 }
227
Cary Clark01cfcdd2010-06-04 16:36:45 -0400228 public void setText(String text) {
229 mEditText.setText(text);
230 findAll();
231 }
232
Leon Scrogginsbff40382010-05-06 16:36:42 -0400233 private void updateMatchesString() {
234 // Note: updateMatchesString is only called by methods that have already
235 // checked mWebView for null.
Eric Fischer8963b292009-03-24 17:53:52 -0700236 String template = mBrowserActivity.getResources().
Leon Scrogginsbff40382010-05-06 16:36:42 -0400237 getQuantityString(R.plurals.matches_found, mNumberOfMatches,
238 mWebView.findIndex() + 1, mNumberOfMatches);
Eric Fischer8963b292009-03-24 17:53:52 -0700239
240 mMatches.setText(template);
241 }
242
The Android Open Source Project0c908882009-03-03 19:32:16 -0800243 public void afterTextChanged(Editable s) {
244 }
245}