blob: 94d6530f735b31b17d9ad9bc9a56ce86b57de327 [file] [log] [blame]
John Reck0f602f32011-07-07 15:38:43 -07001/*
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 */
16package com.android.browser;
17
18import android.app.SearchManager;
19import android.content.Context;
20import android.content.Intent;
21import android.graphics.Bitmap;
22import android.graphics.drawable.Drawable;
23import android.os.Bundle;
24import android.speech.RecognizerResultsIntent;
25import android.util.AttributeSet;
26import android.view.KeyEvent;
27import android.view.Menu;
28import android.view.MenuItem;
29import android.view.View;
30import android.view.View.OnClickListener;
31import android.view.View.OnFocusChangeListener;
32import android.webkit.WebView;
33import android.widget.ImageView;
34import android.widget.LinearLayout;
35import android.widget.PopupMenu;
John Reck58891902011-08-11 17:48:53 -070036import android.widget.PopupMenu.OnDismissListener;
John Reck0f602f32011-07-07 15:38:43 -070037import android.widget.PopupMenu.OnMenuItemClickListener;
38
39import com.android.browser.UI.DropdownChangeListener;
40import com.android.browser.UrlInputView.UrlInputListener;
41import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
42
43import java.util.List;
44
45public class NavigationBarBase extends LinearLayout implements OnClickListener,
46 OnMenuItemClickListener, UrlInputListener, OnFocusChangeListener,
John Reck58891902011-08-11 17:48:53 -070047 TextChangeWatcher, OnDismissListener {
John Reck0f602f32011-07-07 15:38:43 -070048
49 protected BaseUi mBaseUi;
50 protected TitleBar mTitleBar;
51 protected UiController mUiController;
52 protected UrlInputView mUrlInput;
53 protected boolean mInVoiceMode = false;
54
55 private ImageView mFavicon;
56 private ImageView mLockIcon;
57 private View mUaSwitcher;
John Reck58891902011-08-11 17:48:53 -070058 private boolean mUaSwitcherShowing;
59 private PopupMenu mUaSwitcherMenu;
John Reck0f602f32011-07-07 15:38:43 -070060
61 public NavigationBarBase(Context context) {
62 super(context);
63 }
64
65 public NavigationBarBase(Context context, AttributeSet attrs) {
66 super(context, attrs);
67 }
68
69 public NavigationBarBase(Context context, AttributeSet attrs, int defStyle) {
70 super(context, attrs, defStyle);
71 }
72
73 @Override
74 protected void onFinishInflate() {
75 super.onFinishInflate();
76 mLockIcon = (ImageView) findViewById(R.id.lock);
77 mFavicon = (ImageView) findViewById(R.id.favicon);
78 mUrlInput = (UrlInputView) findViewById(R.id.url);
79 mUrlInput.setUrlInputListener(this);
John Reck0f602f32011-07-07 15:38:43 -070080 mUrlInput.setOnFocusChangeListener(this);
81 mUrlInput.setSelectAllOnFocus(true);
82 mUrlInput.addQueryTextWatcher(this);
83 }
84
85 public void setTitleBar(TitleBar titleBar) {
86 mTitleBar = titleBar;
87 mBaseUi = mTitleBar.getUi();
88 mUiController = mTitleBar.getUiController();
Michael Kolbb2e91fd2011-07-14 13:47:29 -070089 mUrlInput.setController(mUiController);
John Reck0f602f32011-07-07 15:38:43 -070090 }
91
92 public void setLock(Drawable d) {
93 if (mLockIcon == null) return;
94 if (d == null) {
95 mLockIcon.setVisibility(View.GONE);
96 } else {
97 mLockIcon.setImageDrawable(d);
98 mLockIcon.setVisibility(View.VISIBLE);
99 }
100 }
101
102 public void setFavicon(Bitmap icon) {
103 if (mFavicon == null) return;
104 mFavicon.setImageDrawable(mBaseUi.getFaviconDrawable(icon));
105 }
106
107 public void setUaSwitcher(View v) {
108 if (mUaSwitcher != null) {
109 mUaSwitcher.setOnClickListener(null);
110 }
111 mUaSwitcher = v;
112 mUaSwitcher.setOnClickListener(this);
113 }
114
115 @Override
116 public void onClick(View v) {
117 if (mUaSwitcher == v) {
118 BrowserSettings settings = BrowserSettings.getInstance();
119 WebView web = mTitleBar.getCurrentWebView();
120 if (web == null) return;
121 boolean desktop = settings.hasDesktopUseragent(web);
John Reck58891902011-08-11 17:48:53 -0700122 mUaSwitcherMenu = new PopupMenu(mContext, mUaSwitcher);
123 Menu menu = mUaSwitcherMenu.getMenu();
124 mUaSwitcherMenu.getMenuInflater().inflate(R.menu.ua_switcher, menu);
John Reck0f602f32011-07-07 15:38:43 -0700125 menu.findItem(R.id.ua_mobile_menu_id).setChecked(!desktop);
126 menu.findItem(R.id.ua_desktop_menu_id).setChecked(desktop);
John Reckeac25cd2011-08-11 16:03:32 -0700127 Tab tab = mUiController.getCurrentTab();
128 MenuItem saveSnapshot = menu.findItem(R.id.save_snapshot_menu_id);
129 saveSnapshot.setVisible(tab != null && !tab.isSnapshot());
130 MenuItem find = menu.findItem(R.id.find_menu_id);
131 find.setVisible(tab != null && !tab.isSnapshot());
John Reck58891902011-08-11 17:48:53 -0700132 mUaSwitcherMenu.setOnMenuItemClickListener(this);
133 mUaSwitcherMenu.setOnDismissListener(this);
134 mUaSwitcherShowing = true;
135 mUaSwitcherMenu.show();
John Reck0f602f32011-07-07 15:38:43 -0700136 }
137 }
138
139 @Override
140 public boolean onMenuItemClick(MenuItem item) {
141 BrowserSettings settings = BrowserSettings.getInstance();
142 WebView web = mTitleBar.getCurrentWebView();
143 if (web == null) return false;
144 boolean desktop = settings.hasDesktopUseragent(web);
145 switch (item.getItemId()) {
146 case R.id.ua_mobile_menu_id:
147 if (desktop) {
148 settings.toggleDesktopUseragent(web);
149 web.loadUrl(web.getOriginalUrl());
150 }
151 return true;
152 case R.id.ua_desktop_menu_id:
153 if (!desktop) {
154 settings.toggleDesktopUseragent(web);
155 web.loadUrl(web.getOriginalUrl());
156 }
157 return true;
158 }
159 return false;
160 }
161
162 @Override
163 public void onFocusChange(View view, boolean hasFocus) {
164 // if losing focus and not in touch mode, leave as is
165 if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) {
166 setFocusState(hasFocus);
167 }
168 if (hasFocus) {
169 mBaseUi.showTitleBar();
170 mUrlInput.forceIme();
171 if (mInVoiceMode) {
172 mUrlInput.forceFilter();
173 }
174 } else if (!mUrlInput.needsUpdate()) {
175 mUrlInput.dismissDropDown();
176 mUrlInput.hideIME();
177 if (mUrlInput.getText().length() == 0) {
178 Tab currentTab = mUiController.getTabControl().getCurrentTab();
179 if (currentTab != null) {
John Reck434e9f82011-08-10 18:16:52 -0700180 setDisplayTitle(currentTab.getUrl());
John Reck0f602f32011-07-07 15:38:43 -0700181 }
182 }
183 mBaseUi.suggestHideTitleBar();
184 }
185 mUrlInput.clearNeedsUpdate();
186 }
187
188 protected void setFocusState(boolean focus) {
189 }
190
191 protected void setSearchMode(boolean voiceSearchEnabled) {}
192
193 public boolean isEditingUrl() {
194 return mUrlInput.hasFocus();
195 }
196
197 void stopEditingUrl() {
198 mUrlInput.clearFocus();
199 }
200
201 void setDisplayTitle(String title) {
202 if (!isEditingUrl()) {
203 mUrlInput.setText(title, false);
204 }
205 }
206
207 // UrlInput text watcher
208
209 @Override
210 public void onTextChanged(String newText) {
211 if (mUrlInput.hasFocus()) {
212 // clear voice mode when user types
213 setInVoiceMode(false, null);
214 }
215 }
216
217 // voicesearch
218
219 public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
220 mInVoiceMode = voicemode;
221 mUrlInput.setVoiceResults(voiceResults);
222 }
223
224 void setIncognitoMode(boolean incognito) {
225 mUrlInput.setIncognitoMode(incognito);
226 }
227
228 void clearCompletions() {
229 mUrlInput.setSuggestedText(null);
230 }
231
232 // UrlInputListener implementation
233
234 /**
235 * callback from suggestion dropdown
236 * user selected a suggestion
237 */
238 @Override
239 public void onAction(String text, String extra, String source) {
240 mUiController.getCurrentTopWebView().requestFocus();
241 if (UrlInputView.TYPED.equals(source)) {
242 String url = UrlUtils.smartUrlFilter(text, false);
243 Tab t = mBaseUi.getActiveTab();
244 // Only shortcut javascript URIs for now, as there is special
245 // logic in UrlHandler for other schemas
246 if (url != null && t != null && url.startsWith("javascript:")) {
247 mUiController.loadUrl(t, url);
248 setDisplayTitle(text);
249 return;
250 }
251 }
252 Intent i = new Intent();
253 String action = null;
254 if (UrlInputView.VOICE.equals(source)) {
255 action = RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS;
256 source = null;
257 } else {
258 action = Intent.ACTION_SEARCH;
259 }
260 i.setAction(action);
261 i.putExtra(SearchManager.QUERY, text);
262 if (extra != null) {
263 i.putExtra(SearchManager.EXTRA_DATA_KEY, extra);
264 }
265 if (source != null) {
266 Bundle appData = new Bundle();
267 appData.putString(com.android.common.Search.SOURCE, source);
268 i.putExtra(SearchManager.APP_DATA, appData);
269 }
270 mUiController.handleNewIntent(i);
271 setDisplayTitle(text);
272 }
273
274 @Override
275 public void onDismiss() {
276 final Tab currentTab = mBaseUi.getActiveTab();
277 mBaseUi.hideTitleBar();
278 post(new Runnable() {
279 public void run() {
280 clearFocus();
281 if ((currentTab != null) && !mInVoiceMode) {
282 setDisplayTitle(currentTab.getUrl());
283 }
284 }
285 });
286 }
287
288 /**
289 * callback from the suggestion dropdown
290 * copy text to input field and stay in edit mode
291 */
292 @Override
293 public void onCopySuggestion(String text) {
294 mUrlInput.setText(text, true);
295 if (text != null) {
296 mUrlInput.setSelection(text.length());
297 }
298 }
299
300 public void setCurrentUrlIsBookmark(boolean isBookmark) {
301 }
302
303 @Override
304 public boolean dispatchKeyEventPreIme(KeyEvent evt) {
305 if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) {
306 // catch back key in order to do slightly more cleanup than usual
307 mUrlInput.clearFocus();
308 return true;
309 }
310 return super.dispatchKeyEventPreIme(evt);
311 }
312
313 void registerDropdownChangeListener(DropdownChangeListener d) {
314 mUrlInput.registerDropdownChangeListener(d);
315 }
316
317 /**
318 * called from the Ui when the user wants to edit
319 * @param clearInput clear the input field
320 */
321 void startEditingUrl(boolean clearInput) {
322 // editing takes preference of progress
323 setVisibility(View.VISIBLE);
324 if (mTitleBar.useQuickControls()) {
325 mTitleBar.getProgressView().setVisibility(View.GONE);
326 }
327 if (!mUrlInput.hasFocus()) {
328 mUrlInput.requestFocus();
329 }
330 if (clearInput) {
331 mUrlInput.setText("");
332 } else if (mInVoiceMode) {
333 mUrlInput.showDropDown();
334 }
335 }
336
337 public void onProgressStarted() {
338 }
339
340 public void onProgressStopped() {
341 }
342
John Reck58891902011-08-11 17:48:53 -0700343 @Override
344 public void onDismiss(PopupMenu menu) {
345 if (mUaSwitcherMenu == menu) {
346 mUaSwitcherShowing = false;
347 mUaSwitcherMenu = null;
348 mBaseUi.showTitleBarForDuration();
349 }
350 }
351
352 public boolean isMenuShowing() {
353 return mUaSwitcherShowing;
354 }
355
John Reck0f602f32011-07-07 15:38:43 -0700356}