Home | History | Annotate | Download | only in browser
      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 }
    215