OSDN Git Service

refactor find state and scrolling
[android-x86/packages-apps-Browser.git] / src / com / android / browser / FindDialog.java
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
17 package com.android.browser;
18
19 import android.app.Dialog;
20 import android.content.Context;
21 import android.os.Bundle;
22 import android.text.Editable;
23 import android.text.Spannable;
24 import android.text.TextWatcher;
25 import android.view.Gravity;
26 import android.view.KeyEvent;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.view.Window;
30 import android.view.WindowManager;
31 import android.view.inputmethod.InputMethodManager;
32 import android.webkit.WebView;
33 import android.widget.EditText;
34 import android.widget.TextView;
35
36 /* package */ class FindDialog extends Dialog implements TextWatcher {
37     private WebView         mWebView;
38     private TextView        mMatches;
39     private BrowserActivity mBrowserActivity;
40     
41     // Views with which the user can interact.
42     private EditText        mEditText;
43     private View            mNextButton;
44     private View            mPrevButton;
45     private View            mMatchesView;
46
47     private View.OnClickListener mFindListener = new View.OnClickListener() {
48         public void onClick(View v) {
49             findNext();
50         }
51     };
52
53     private View.OnClickListener mFindCancelListener  = 
54             new View.OnClickListener() {
55         public void onClick(View v) {
56             dismiss();
57         }
58     };
59     
60     private View.OnClickListener mFindPreviousListener  = 
61             new View.OnClickListener() {
62         public void onClick(View v) {
63             if (mWebView == null) {
64                 throw new AssertionError("No WebView for FindDialog::onClick");
65             }
66             mWebView.findNext(false);
67             hideSoftInput();
68         }
69     };
70
71     /*
72      * Remove the soft keyboard from the screen.
73      */
74     private void hideSoftInput() {
75         InputMethodManager imm = (InputMethodManager)
76                 mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
77         imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
78     }
79
80     private void disableButtons() {
81         mPrevButton.setEnabled(false);
82         mNextButton.setEnabled(false);
83         mPrevButton.setFocusable(false);
84         mNextButton.setFocusable(false);
85     }
86
87     /* package */ void setWebView(WebView webview) {
88         mWebView = webview;
89     }
90
91     /* package */ FindDialog(BrowserActivity context) {
92         super(context, R.style.FindDialogTheme);
93         mBrowserActivity = context;
94         setCanceledOnTouchOutside(true);
95     }
96
97     @Override
98     protected void onCreate(Bundle savedInstanceState) {
99         super.onCreate(savedInstanceState);
100
101         Window theWindow = getWindow();
102         theWindow.setGravity(Gravity.BOTTOM|Gravity.FILL_HORIZONTAL);
103
104         setContentView(R.layout.browser_find);
105
106         theWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
107                 ViewGroup.LayoutParams.WRAP_CONTENT);
108
109         mEditText = (EditText) findViewById(R.id.edit);
110         
111         View button = findViewById(R.id.next);
112         button.setOnClickListener(mFindListener);
113         mNextButton = button;
114         
115         button = findViewById(R.id.previous);
116         button.setOnClickListener(mFindPreviousListener);
117         mPrevButton = button;
118         
119         button = findViewById(R.id.done);
120         button.setOnClickListener(mFindCancelListener);
121         
122         mMatches = (TextView) findViewById(R.id.matches);
123         mMatchesView = findViewById(R.id.matches_view);
124         disableButtons();
125         theWindow.setSoftInputMode(
126                 WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
127     }
128     
129     public void dismiss() {
130         super.dismiss();
131         mBrowserActivity.closeFind();
132         mWebView.notifyFindDialogDismissed();
133     }
134
135     @Override
136     public boolean dispatchKeyEvent(KeyEvent event) {
137         if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
138                 && event.getAction() == KeyEvent.ACTION_UP
139                 && mEditText.hasFocus()) {
140             findNext();
141             return true;
142         }
143         return super.dispatchKeyEvent(event);
144     }
145
146     private void findNext() {
147         if (mWebView == null) {
148             throw new AssertionError("No WebView for FindDialog::findNext");
149         }
150         mWebView.findNext(true);
151         hideSoftInput();
152     }
153
154     public void show() {
155         super.show();
156         mEditText.requestFocus();
157         mEditText.setText("");
158         Spannable span = (Spannable) mEditText.getText();
159         span.setSpan(this, 0, span.length(), 
160                      Spannable.SPAN_INCLUSIVE_INCLUSIVE);
161         setMatchesFound(0);
162         disableButtons();
163     }
164     
165     // TextWatcher methods
166     public void beforeTextChanged(CharSequence s, 
167                                   int start, 
168                                   int count, 
169                                   int after) {
170     }
171     
172     public void onTextChanged(CharSequence s,  
173                               int start, 
174                               int before, 
175                               int count) {
176         if (mWebView == null) {
177             throw new AssertionError(
178                     "No WebView for FindDialog::onTextChanged");
179         }
180         CharSequence find = mEditText.getText();
181         if (0 == find.length()) {
182             disableButtons();
183             mWebView.clearMatches();
184             mMatchesView.setVisibility(View.INVISIBLE);
185         } else {
186             mMatchesView.setVisibility(View.VISIBLE);
187             mWebView.setFindDialogHeight(
188                 getWindow().getDecorView().getHeight());
189             int found = mWebView.findAll(find.toString());
190             setMatchesFound(found);
191             if (found < 2) {
192                 disableButtons();
193                 if (found == 0) {
194                     setMatchesFound(0);
195                 }
196             } else {
197                 mPrevButton.setFocusable(true);
198                 mNextButton.setFocusable(true);
199                 mPrevButton.setEnabled(true);
200                 mNextButton.setEnabled(true);
201             }
202         }
203     }
204
205     private void setMatchesFound(int found) {
206         String template = mBrowserActivity.getResources().
207                 getQuantityString(R.plurals.matches_found, found, found);
208
209         mMatches.setText(template);
210     }
211
212     public void afterTextChanged(Editable s) {
213     }
214 }