blob: 726138ef0a56eaddd47340921e821b1207756e62 [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;
Cary Clark2c326e62010-08-19 18:40:57 -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;
Cary Clark2c326e62010-08-19 18:40:57 -040026import android.view.LayoutInflater;
The Android Open Source Project0c908882009-03-03 19:32:16 -080027import android.view.View;
28import android.view.ViewGroup;
Cary Clark2c326e62010-08-19 18:40:57 -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;
Cary Clark2c326e62010-08-19 18:40:57 -040033import android.widget.LinearLayout;
The Android Open Source Project0c908882009-03-03 19:32:16 -080034import android.widget.TextView;
35
Cary Clark2c326e62010-08-19 18:40:57 -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
Cary Clark2c326e62010-08-19 18:40:57 -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;
49 private int mNumberOfMatches;
50
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 Clark2c326e62010-08-19 18:40:57 -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);
Cary Clark2c326e62010-08-19 18:40:57 -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) {
Cary Clark2c326e62010-08-19 18:40:57 -040077 super(context);
The Android Open Source Project0c908882009-03-03 19:32:16 -080078
Cary Clark2c326e62010-08-19 18:40:57 -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 Clark2c326e62010-08-19 18:40:57 -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();
Cary Clark2c326e62010-08-19 18:40:57 -040096
The Android Open Source Project0c908882009-03-03 19:32:16 -080097 }
Cary Clark2c326e62010-08-19 18:40:57 -040098
99 /**
100 * Called by BrowserActivity.closeDialog. Start the animation to hide
101 * 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() {
105 super.dismiss();
Cary Clark7d3ac792010-03-03 10:11:44 -0500106 mWebView.notifyFindDialogDismissed();
Cary Clark2c326e62010-08-19 18:40:57 -0400107 hideSoftInput();
108 }
109
110 @Override
111 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)) {
122 mBrowserActivity.closeDialogs();
123 return true;
124 }
125 }
126 }
127 return super.dispatchKeyEventPreIme(event);
The Android Open Source Project0c908882009-03-03 19:32:16 -0800128 }
Leon Scroggins354bbd02009-04-16 15:24:07 -0400129
The Android Open Source Project0c908882009-03-03 19:32:16 -0800130 @Override
131 public boolean dispatchKeyEvent(KeyEvent event) {
Cary Clark2c326e62010-08-19 18:40:57 -0400132 int keyCode = event.getKeyCode();
133 if (event.getAction() == KeyEvent.ACTION_UP) {
134 if (keyCode == KeyEvent.KEYCODE_ENTER
135 && mEditText.hasFocus()) {
136 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 }
144 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);
Cary Clark2c326e62010-08-19 18:40:57 -0400155 updateMatchesString();
The Android Open Source Project0c908882009-03-03 19:32:16 -0800156 hideSoftInput();
157 }
158
159 public void show() {
160 super.show();
Cary Clark2c326e62010-08-19 18:40:57 -0400161 // In case the matches view is showing from a previous search
162 mMatchesView.setVisibility(View.INVISIBLE);
163 mMatchesFound = false;
164 // 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();
Cary Clark2c326e62010-08-19 18:40:57 -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();
Cary Clark2c326e62010-08-19 18:40:57 -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) {
Cary Clark2c326e62010-08-19 18:40:57 -0400188 findAll();
189 }
190
191 private void findAll() {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800192 if (mWebView == null) {
193 throw new AssertionError(
Cary Clark2c326e62010-08-19 18:40:57 -0400194 "No WebView for FindDialog::findAll");
The Android Open Source Project0c908882009-03-03 19:32:16 -0800195 }
196 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());
Cary Clark2c326e62010-08-19 18:40:57 -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) {
Cary Clark2c326e62010-08-19 18:40:57 -0400209 // Cannot use getQuantityString, which ignores the "zero"
210 // quantity.
211 // FIXME: is this fix is beyond the scope
212 // of adding touch selection to gingerbread?
213 // mMatches.setText(mBrowserActivity.getResources().getString(
214 // R.string.no_matches));
The Android Open Source Project0c908882009-03-03 19:32:16 -0800215 }
216 } else {
217 mPrevButton.setFocusable(true);
218 mNextButton.setFocusable(true);
219 mPrevButton.setEnabled(true);
220 mNextButton.setEnabled(true);
221 }
222 }
223 }
224
Eric Fischer8963b292009-03-24 17:53:52 -0700225 private void setMatchesFound(int found) {
Cary Clark2c326e62010-08-19 18:40:57 -0400226 mNumberOfMatches = found;
227 updateMatchesString();
228 }
229
230 public void setText(String text) {
231 mEditText.setText(text);
232 findAll();
233 }
234
235 private void updateMatchesString() {
236 // Note: updateMatchesString is only called by methods that have already
237 // checked mWebView for null.
Eric Fischer8963b292009-03-24 17:53:52 -0700238 String template = mBrowserActivity.getResources().
Cary Clark2c326e62010-08-19 18:40:57 -0400239 getQuantityString(R.plurals.matches_found, mNumberOfMatches,
240 mWebView.findIndex() + 1, mNumberOfMatches);
Eric Fischer8963b292009-03-24 17:53:52 -0700241
242 mMatches.setText(template);
243 }
244
The Android Open Source Project0c908882009-03-03 19:32:16 -0800245 public void afterTextChanged(Editable s) {
246 }
247}