1 /*
2  * Copyright (C) 2011 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 package com.android.browser;
17 
18 import android.app.SearchManager;
19 import android.content.Context;
20 import android.content.Intent;
21 import android.graphics.Bitmap;
22 import android.graphics.drawable.Drawable;
23 import android.os.Bundle;
24 import android.text.Editable;
25 import android.text.TextWatcher;
26 import android.util.AttributeSet;
27 import android.view.KeyEvent;
28 import android.view.View;
29 import android.view.View.OnClickListener;
30 import android.view.View.OnFocusChangeListener;
31 import android.webkit.WebView;
32 import android.widget.ImageView;
33 import android.widget.LinearLayout;
34 
35 import com.android.browser.UrlInputView.UrlInputListener;
36 
37 public class NavigationBarBase extends LinearLayout implements
38         OnClickListener, UrlInputListener, OnFocusChangeListener,
39         TextWatcher {
40 
41     protected BaseUi mBaseUi;
42     protected TitleBar mTitleBar;
43     protected UiController mUiController;
44     protected UrlInputView mUrlInput;
45 
46     private ImageView mFavicon;
47     private ImageView mLockIcon;
48 
NavigationBarBase(Context context)49     public NavigationBarBase(Context context) {
50         super(context);
51     }
52 
NavigationBarBase(Context context, AttributeSet attrs)53     public NavigationBarBase(Context context, AttributeSet attrs) {
54         super(context, attrs);
55     }
56 
NavigationBarBase(Context context, AttributeSet attrs, int defStyle)57     public NavigationBarBase(Context context, AttributeSet attrs, int defStyle) {
58         super(context, attrs, defStyle);
59     }
60 
61     @Override
onFinishInflate()62     protected void onFinishInflate() {
63         super.onFinishInflate();
64         mLockIcon = (ImageView) findViewById(R.id.lock);
65         mFavicon = (ImageView) findViewById(R.id.favicon);
66         mUrlInput = (UrlInputView) findViewById(R.id.url);
67         mUrlInput.setUrlInputListener(this);
68         mUrlInput.setOnFocusChangeListener(this);
69         mUrlInput.setSelectAllOnFocus(true);
70         mUrlInput.addTextChangedListener(this);
71     }
72 
setTitleBar(TitleBar titleBar)73     public void setTitleBar(TitleBar titleBar) {
74         mTitleBar = titleBar;
75         mBaseUi = mTitleBar.getUi();
76         mUiController = mTitleBar.getUiController();
77         mUrlInput.setController(mUiController);
78     }
79 
setLock(Drawable d)80     public void setLock(Drawable d) {
81         if (mLockIcon == null) return;
82         if (d == null) {
83             mLockIcon.setVisibility(View.GONE);
84         } else {
85             mLockIcon.setImageDrawable(d);
86             mLockIcon.setVisibility(View.VISIBLE);
87         }
88     }
89 
setFavicon(Bitmap icon)90     public void setFavicon(Bitmap icon) {
91         if (mFavicon == null) return;
92         mFavicon.setImageDrawable(mBaseUi.getFaviconDrawable(icon));
93     }
94 
95     @Override
onClick(View v)96     public void onClick(View v) {
97     }
98 
99     @Override
onFocusChange(View view, boolean hasFocus)100     public void onFocusChange(View view, boolean hasFocus) {
101         // if losing focus and not in touch mode, leave as is
102         if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) {
103             setFocusState(hasFocus);
104         }
105         if (hasFocus) {
106             mBaseUi.showTitleBar();
107         } else if (!mUrlInput.needsUpdate()) {
108             mUrlInput.dismissDropDown();
109             mUrlInput.hideIME();
110             if (mUrlInput.getText().length() == 0) {
111                 Tab currentTab = mUiController.getTabControl().getCurrentTab();
112                 if (currentTab != null) {
113                     setDisplayTitle(currentTab.getUrl());
114                 }
115             }
116             mBaseUi.suggestHideTitleBar();
117         }
118         mUrlInput.clearNeedsUpdate();
119     }
120 
setFocusState(boolean focus)121     protected void setFocusState(boolean focus) {
122     }
123 
isEditingUrl()124     public boolean isEditingUrl() {
125         return mUrlInput.hasFocus();
126     }
127 
stopEditingUrl()128     void stopEditingUrl() {
129         WebView currentTopWebView = mUiController.getCurrentTopWebView();
130         if (currentTopWebView != null) {
131             currentTopWebView.requestFocus();
132         }
133     }
134 
setDisplayTitle(String title)135     void setDisplayTitle(String title) {
136         if (!isEditingUrl()) {
137             if (!title.equals(mUrlInput.getText().toString())) {
138                 mUrlInput.setText(title, false);
139             }
140         }
141     }
142 
setIncognitoMode(boolean incognito)143     void setIncognitoMode(boolean incognito) {
144         mUrlInput.setIncognitoMode(incognito);
145     }
146 
clearCompletions()147     void clearCompletions() {
148         mUrlInput.dismissDropDown();
149     }
150 
151  // UrlInputListener implementation
152 
153     /**
154      * callback from suggestion dropdown
155      * user selected a suggestion
156      */
157     @Override
onAction(String text, String extra, String source)158     public void onAction(String text, String extra, String source) {
159         stopEditingUrl();
160         if (UrlInputView.TYPED.equals(source)) {
161             String url = UrlUtils.smartUrlFilter(text, false);
162             Tab t = mBaseUi.getActiveTab();
163             // Only shortcut javascript URIs for now, as there is special
164             // logic in UrlHandler for other schemas
165             if (url != null && t != null && url.startsWith("javascript:")) {
166                 mUiController.loadUrl(t, url);
167                 setDisplayTitle(text);
168                 return;
169             }
170         }
171         Intent i = new Intent();
172         String action = Intent.ACTION_SEARCH;
173         i.setAction(action);
174         i.putExtra(SearchManager.QUERY, text);
175         if (extra != null) {
176             i.putExtra(SearchManager.EXTRA_DATA_KEY, extra);
177         }
178         if (source != null) {
179             Bundle appData = new Bundle();
180             appData.putString(com.android.common.Search.SOURCE, source);
181             i.putExtra(SearchManager.APP_DATA, appData);
182         }
183         mUiController.handleNewIntent(i);
184         setDisplayTitle(text);
185     }
186 
187     @Override
onDismiss()188     public void onDismiss() {
189         final Tab currentTab = mBaseUi.getActiveTab();
190         mBaseUi.hideTitleBar();
191         post(new Runnable() {
192             public void run() {
193                 clearFocus();
194                 if (currentTab != null) {
195                     setDisplayTitle(currentTab.getUrl());
196                 }
197             }
198         });
199     }
200 
201     /**
202      * callback from the suggestion dropdown
203      * copy text to input field and stay in edit mode
204      */
205     @Override
onCopySuggestion(String text)206     public void onCopySuggestion(String text) {
207         mUrlInput.setText(text, true);
208         if (text != null) {
209             mUrlInput.setSelection(text.length());
210         }
211     }
212 
setCurrentUrlIsBookmark(boolean isBookmark)213     public void setCurrentUrlIsBookmark(boolean isBookmark) {
214     }
215 
216     @Override
dispatchKeyEventPreIme(KeyEvent evt)217     public boolean dispatchKeyEventPreIme(KeyEvent evt) {
218         if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) {
219             // catch back key in order to do slightly more cleanup than usual
220             stopEditingUrl();
221             return true;
222         }
223         return super.dispatchKeyEventPreIme(evt);
224     }
225 
226     /**
227      * called from the Ui when the user wants to edit
228      * @param clearInput clear the input field
229      */
startEditingUrl(boolean clearInput, boolean forceIME)230     void startEditingUrl(boolean clearInput, boolean forceIME) {
231         // editing takes preference of progress
232         setVisibility(View.VISIBLE);
233         if (mTitleBar.useQuickControls()) {
234             mTitleBar.getProgressView().setVisibility(View.GONE);
235         }
236         if (!mUrlInput.hasFocus()) {
237             mUrlInput.requestFocus();
238         }
239         if (clearInput) {
240             mUrlInput.setText("");
241         }
242         if (forceIME) {
243             mUrlInput.showIME();
244         }
245     }
246 
onProgressStarted()247     public void onProgressStarted() {
248     }
249 
onProgressStopped()250     public void onProgressStopped() {
251     }
252 
isMenuShowing()253     public boolean isMenuShowing() {
254         return false;
255     }
256 
onTabDataChanged(Tab tab)257     public void onTabDataChanged(Tab tab) {
258     }
259 
onVoiceResult(String s)260     public void onVoiceResult(String s) {
261         startEditingUrl(true, true);
262         onCopySuggestion(s);
263     }
264 
265     @Override
beforeTextChanged(CharSequence s, int start, int count, int after)266     public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
267 
268     @Override
onTextChanged(CharSequence s, int start, int before, int count)269     public void onTextChanged(CharSequence s, int start, int before, int count) { }
270 
271     @Override
afterTextChanged(Editable s)272     public void afterTextChanged(Editable s) { }
273 
274 }
275