FindDialog.java revision 8963b29db97943e82f8780b3ef65a40d788634b7
1/* 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 19import android.app.Dialog; 20import android.content.Context; 21import android.content.res.Configuration; 22import android.os.Bundle; 23import android.os.Handler; 24import android.os.Message; 25import android.text.Editable; 26import android.text.Spannable; 27import android.text.TextWatcher; 28import android.view.Gravity; 29import android.view.KeyEvent; 30import android.view.View; 31import android.view.ViewGroup; 32import android.view.Window; 33import android.view.WindowManager; 34import android.view.inputmethod.InputMethodManager; 35import android.webkit.WebView; 36import android.widget.EditText; 37import android.widget.TextView; 38 39/* package */ class FindDialog extends Dialog implements TextWatcher { 40 private WebView mWebView; 41 private TextView mMatches; 42 private BrowserActivity mBrowserActivity; 43 44 // Views with which the user can interact. 45 private View mOk; 46 private EditText mEditText; 47 private View mNextButton; 48 private View mPrevButton; 49 private View mMatchesView; 50 51 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) { 60 dismiss(); 61 } 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) { 96 super(context, R.style.FindDialogTheme); 97 mBrowserActivity = context; 98 setCanceledOnTouchOutside(true); 99 } 100 101 /* package */ void onConfigurationChanged(Configuration newConfig) { 102 // FIXME: Would like to call mWebView.findAll again, so that the 103 // matches would refresh, but the new picture has not yet been 104 // created, so it is too soon. 105 mEditText.getText().clear(); 106 } 107 108 @Override 109 protected void onCreate(Bundle savedInstanceState) { 110 super.onCreate(savedInstanceState); 111 112 Window theWindow = getWindow(); 113 theWindow.setGravity(Gravity.BOTTOM|Gravity.FILL_HORIZONTAL); 114 115 setContentView(R.layout.browser_find); 116 117 theWindow.setLayout(ViewGroup.LayoutParams.FILL_PARENT, 118 ViewGroup.LayoutParams.WRAP_CONTENT); 119 120 mEditText = (EditText) findViewById(R.id.edit); 121 122 View button = findViewById(R.id.next); 123 button.setOnClickListener(mFindListener); 124 mNextButton = button; 125 126 button = findViewById(R.id.previous); 127 button.setOnClickListener(mFindPreviousListener); 128 mPrevButton = button; 129 130 button = findViewById(R.id.done); 131 button.setOnClickListener(mFindCancelListener); 132 mOk = button; 133 134 mMatches = (TextView) findViewById(R.id.matches); 135 mMatchesView = findViewById(R.id.matches_view); 136 disableButtons(); 137 theWindow.setSoftInputMode( 138 WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 139 } 140 141 public void dismiss() { 142 super.dismiss(); 143 mBrowserActivity.closeFind(); 144 mWebView.clearMatches(); 145 } 146 147 @Override 148 public boolean dispatchKeyEvent(KeyEvent event) { 149 int code = event.getKeyCode(); 150 boolean up = event.getAction() == KeyEvent.ACTION_UP; 151 switch (code) { 152 case KeyEvent.KEYCODE_DPAD_CENTER: 153 case KeyEvent.KEYCODE_ENTER: 154 if (!mEditText.hasFocus()) { 155 break; 156 } 157 if (up) { 158 findNext(); 159 } 160 return true; 161 default: 162 break; 163 } 164 return super.dispatchKeyEvent(event); 165 } 166 167 private void findNext() { 168 if (mWebView == null) { 169 throw new AssertionError("No WebView for FindDialog::findNext"); 170 } 171 mWebView.findNext(true); 172 hideSoftInput(); 173 } 174 175 public void show() { 176 super.show(); 177 mEditText.requestFocus(); 178 mEditText.setText(""); 179 Spannable span = (Spannable) mEditText.getText(); 180 span.setSpan(this, 0, span.length(), 181 Spannable.SPAN_INCLUSIVE_INCLUSIVE); 182 setMatchesFound(0); 183 disableButtons(); 184 } 185 186 // TextWatcher methods 187 public void beforeTextChanged(CharSequence s, 188 int start, 189 int count, 190 int after) { 191 } 192 193 public void onTextChanged(CharSequence s, 194 int start, 195 int before, 196 int count) { 197 if (mWebView == null) { 198 throw new AssertionError( 199 "No WebView for FindDialog::onTextChanged"); 200 } 201 CharSequence find = mEditText.getText(); 202 if (0 == find.length()) { 203 disableButtons(); 204 mWebView.clearMatches(); 205 mMatchesView.setVisibility(View.INVISIBLE); 206 } else { 207 mMatchesView.setVisibility(View.VISIBLE); 208 int found = mWebView.findAll(find.toString()); 209 setMatchesFound(found); 210 if (found < 2) { 211 disableButtons(); 212 if (found == 0) { 213 setMatchesFound(0); 214 } 215 } else { 216 mPrevButton.setFocusable(true); 217 mNextButton.setFocusable(true); 218 mPrevButton.setEnabled(true); 219 mNextButton.setEnabled(true); 220 } 221 } 222 } 223 224 private void setMatchesFound(int found) { 225 String template = mBrowserActivity.getResources(). 226 getQuantityString(R.plurals.matches_found, found, found); 227 228 mMatches.setText(template); 229 } 230 231 public void afterTextChanged(Editable s) { 232 } 233} 234